Add direct remote copying in Tramp's scp support
* doc/misc/tramp.texi: Use @trampfn{} function where possible. (Top, Configuration): Insert section 'Ssh setup' and remove section 'Windows setup hints' in menu. (Default Method): Mention tramp-use-scp-direct-remote-copying. (Ssh setup): New node. (Windows setup hints): Move it to that new node. (Frequently Asked Questions): Move items about ssh config to that node. * etc/NEWS: Add Tramp's direct remote copying feature. Fix typos. * lisp/net/tramp-sh.el (tramp-use-scp-direct-remote-copying): New defcustom. (tramp-methods) <scp, scpx>: Add "%y" marker. (tramp-scp-direct-remote-copying): New defun. (tramp-do-copy-or-rename-file-out-of-band): Extend for direct remote copying. * lisp/net/tramp.el (tramp-methods): Extend docstring. (tramp-password-prompt-not-unique): New defvar. (tramp-read-passwd): Adapt docstring. (tramp-read-passwd-without-cache): New defun. (tramp-action-password): Call it.
This commit is contained in:
parent
1edde2fc7a
commit
6139a05241
4 changed files with 594 additions and 402 deletions
|
@ -133,19 +133,21 @@ Configuring @value{tramp} for use
|
|||
* Multi-hops:: Connecting to a remote host using multiple hops.
|
||||
* Firewalls:: Passing firewalls.
|
||||
* Customizing Methods:: Using Non-Standard Methods.
|
||||
* Customizing Completion:: Selecting config files for user/host name completion.
|
||||
* Customizing Completion:: Selecting config files for user/host name @c
|
||||
completion.
|
||||
* Password handling:: Reusing passwords for several connections.
|
||||
* Connection caching:: Reusing connection related information.
|
||||
* Predefined connection information::
|
||||
Setting own connection related information.
|
||||
* Remote programs:: How @value{tramp} finds and uses programs on the remote host.
|
||||
* Remote programs:: How @value{tramp} finds and uses programs @c
|
||||
on the remote host.
|
||||
* Remote shell setup:: Remote shell setup hints.
|
||||
* Ssh setup:: Ssh setup hints.
|
||||
* FUSE setup:: @acronym{FUSE} setup hints.
|
||||
* Android shell setup:: Android shell setup hints.
|
||||
* Auto-save File Lock and Backup::
|
||||
Auto-save, File Lock and Backup.
|
||||
* Keeping files encrypted:: Protect remote files by encryption.
|
||||
* Windows setup hints:: Issues with Cygwin ssh.
|
||||
|
||||
Using @value{tramp}
|
||||
|
||||
|
@ -523,7 +525,7 @@ performed on another host, it can be comnbined with a leading
|
|||
connects first to the other host with non-administrative credentials,
|
||||
and changes to administrative credentials on that host afterwards. In
|
||||
a simple case, the syntax looks like
|
||||
@file{@value{prefix}ssh@value{postfixhop}user@@host|sudo@value{postfixhop}@value{postfix}/path/to/file}.
|
||||
@file{@trampfn{ssh@value{postfixhop}user@@host|sudo,,/path/to/file}}.
|
||||
@xref{Ad-hoc multi-hops}.
|
||||
|
||||
|
||||
|
@ -683,19 +685,21 @@ may be used in your init file:
|
|||
* Multi-hops:: Connecting to a remote host using multiple hops.
|
||||
* Firewalls:: Passing firewalls.
|
||||
* Customizing Methods:: Using Non-Standard Methods.
|
||||
* Customizing Completion:: Selecting config files for user/host name completion.
|
||||
* Customizing Completion:: Selecting config files for user/host name @c
|
||||
completion.
|
||||
* Password handling:: Reusing passwords for several connections.
|
||||
* Connection caching:: Reusing connection related information.
|
||||
* Predefined connection information::
|
||||
Setting own connection related information.
|
||||
* Remote programs:: How @value{tramp} finds and uses programs on the remote host.
|
||||
* Remote programs:: How @value{tramp} finds and uses programs @c
|
||||
on the remote host.
|
||||
* Remote shell setup:: Remote shell setup hints.
|
||||
* Ssh setup:: Ssh setup hints.
|
||||
* FUSE setup:: @acronym{FUSE} setup hints.
|
||||
* Android shell setup:: Android shell setup hints.
|
||||
* Auto-save File Lock and Backup::
|
||||
Auto-save, File Lock and Backup.
|
||||
* Keeping files encrypted:: Protect remote files by encryption.
|
||||
* Windows setup hints:: Issues with Cygwin ssh.
|
||||
@end menu
|
||||
|
||||
|
||||
|
@ -1234,7 +1238,8 @@ be populated in your @command{Online Accounts} application outside Emacs.
|
|||
Since Google Drive uses cryptic blob file names internally,
|
||||
@value{tramp} works with the @code{display-name} of the files. This
|
||||
could produce unexpected behavior in case two files in the same
|
||||
directory have the same @code{display-name}, such a situation must be avoided.
|
||||
directory have the same @code{display-name}, such a situation must be
|
||||
avoided.
|
||||
|
||||
@item @option{mtp}
|
||||
@cindex method @option{mtp}
|
||||
|
@ -1448,7 +1453,7 @@ External methods might be more efficient for large files, but most
|
|||
@value{tramp} users edit small files more often than large files.
|
||||
|
||||
Enable compression, @code{tramp-inline-compress-start-size}, for a
|
||||
performance boost for large files.
|
||||
performance boost for large files with inline methods.
|
||||
|
||||
Since @command{ssh} has become the most common method of remote host
|
||||
access and it has the most reasonable security protocols, use
|
||||
|
@ -1474,6 +1479,10 @@ For editing large files, @option{scp} is faster than @option{ssh}.
|
|||
@option{pscp} is faster than @option{plink}. But this speed
|
||||
improvement is not always true.
|
||||
|
||||
When copying large files between two different remote hosts via
|
||||
@option{scp}, set @code{tramp-use-scp-direct-remote-copying} to
|
||||
non-@code{nil}.
|
||||
|
||||
|
||||
@node Default User
|
||||
@section Selecting a default user
|
||||
|
@ -1689,8 +1698,8 @@ Sometimes, it is not possible to reach a remote host directly. A
|
|||
firewall might be in the way, which could be passed via a proxy
|
||||
server.
|
||||
|
||||
Both ssh and PuTTY support such proxy settings, using an HTTP tunnel
|
||||
via the @command{CONNECT} command (conforming to RFC 2616, 2817
|
||||
Both OpenSSH and PuTTY support such proxy settings, using an HTTP
|
||||
tunnel via the @command{CONNECT} command (conforming to RFC 2616, 2817
|
||||
specifications). Proxy servers using HTTP 1.1 or later protocol
|
||||
support this command.
|
||||
|
||||
|
@ -1804,7 +1813,7 @@ hadoop server.
|
|||
@cindex @option{vagrant} method
|
||||
Convenience method to access vagrant boxes. It is often used in
|
||||
multi-hop file names like
|
||||
@file{@value{prefix}vagrant@value{postfixhop}box|sudo@value{postfixhop}box@value{postfix}/path/to/file},
|
||||
@file{@trampfn{vagrant@value{postfixhop}box|sudo,box,/path/to/file}},
|
||||
where @samp{box} is the name of the vagrant box.
|
||||
|
||||
@end table
|
||||
|
@ -2606,6 +2615,211 @@ where @samp{192.168.0.1} is the remote host IP address
|
|||
@end table
|
||||
|
||||
|
||||
@node Ssh setup
|
||||
@section Ssh setup hints
|
||||
|
||||
The most common @value{tramp} connection family is based on either
|
||||
@command{ssh} or @command{scp} of OpenSSH, or @command{plink} or
|
||||
@command{pscp} of PuTTY on MS Windows. In the following, some
|
||||
configuration recommendations are given.
|
||||
|
||||
|
||||
@subsection Detection of session hangouts
|
||||
|
||||
@vindex ServerAliveInterval@r{, ssh option}
|
||||
@vindex ServerAliveCountMax@r{, ssh option}
|
||||
@command{ssh} sessions on the local host hang when the network is
|
||||
down. @value{tramp} cannot safely detect such hangs. OpenSSH can be
|
||||
configured to kill such hangs with the following settings in
|
||||
@file{~/.ssh/config}:
|
||||
|
||||
@example
|
||||
@group
|
||||
Host *
|
||||
ServerAliveInterval 5
|
||||
ServerAliveCountMax 2
|
||||
@end group
|
||||
@end example
|
||||
|
||||
The corresponding PuTTY configuration is in the @option{Connection}
|
||||
entry, @option{Seconds between keepalives} option. Set this to 5.
|
||||
There is no counter which could be set.
|
||||
|
||||
|
||||
@subsection Using ssh connection sharing
|
||||
|
||||
@vindex ControlPath@r{, ssh option}
|
||||
@vindex ControlPersist@r{, ssh option}
|
||||
@value{tramp} uses the @option{ControlMaster=auto} OpenSSH option by
|
||||
default, if possible. However, it overwrites @option{ControlPath}
|
||||
settings when initiating @command{ssh} sessions. @value{tramp} does
|
||||
this to fend off a stall if a master session opened outside the Emacs
|
||||
session is no longer open. That is why @value{tramp} prompts for the
|
||||
password again even if there is an @command{ssh} already open.
|
||||
|
||||
@vindex tramp-ssh-controlmaster-options
|
||||
Some OpenSSH versions support a @option{ControlPersist} option, which
|
||||
allows you to set the @option{ControlPath} provided the variable
|
||||
@code{tramp-ssh-controlmaster-options} is customized as follows:
|
||||
|
||||
@lisp
|
||||
@group
|
||||
(customize-set-variable
|
||||
'tramp-ssh-controlmaster-options
|
||||
(concat
|
||||
"-o ControlPath=/tmp/ssh-ControlPath-%%r@@%%h:%%p "
|
||||
"-o ControlMaster=auto -o ControlPersist=yes"))
|
||||
@end group
|
||||
@end lisp
|
||||
|
||||
Note how @samp{%r}, @samp{%h} and @samp{%p} must be encoded as
|
||||
@samp{%%r}, @samp{%%h} and @samp{%%p}.
|
||||
|
||||
@vindex tramp-use-ssh-controlmaster-options
|
||||
If the @file{~/.ssh/config} file is configured appropriately for the
|
||||
above behavior, then any changes to @command{ssh} can be suppressed
|
||||
with this @code{nil} setting:
|
||||
|
||||
@lisp
|
||||
(customize-set-variable 'tramp-use-ssh-controlmaster-options nil)
|
||||
@end lisp
|
||||
|
||||
@vindex ProxyCommand@r{, ssh option}
|
||||
@vindex ProxyJump@r{, ssh option}
|
||||
This should also be set to @code{nil} if you use the
|
||||
@option{ProxyCommand} or @option{ProxyJump} options in your
|
||||
@command{ssh} configuration.
|
||||
|
||||
In order to use the @option{ControlMaster} option, @value{tramp} must
|
||||
check whether the @command{ssh} client supports this option. This is
|
||||
only possible on the local host, for the first hop. @value{tramp}
|
||||
does not use this option on proxy hosts, therefore.
|
||||
|
||||
If you want to use this option also for the other hops, you must
|
||||
configure @file{~/.ssh/config} on the proxy host:
|
||||
|
||||
@example
|
||||
@group
|
||||
Host *
|
||||
ControlMaster auto
|
||||
ControlPath tramp.%C
|
||||
ControlPersist no
|
||||
@end group
|
||||
@end example
|
||||
|
||||
Check the @samp{ssh_config(5)} man page whether these options are
|
||||
supported on your proxy host.
|
||||
|
||||
On MS Windows, @code{tramp-use-ssh-controlmaster-options} is set to
|
||||
@code{nil} by default, because the MS Windows and MSYS2
|
||||
implementations of @command{OpenSSH} do not support this option properly.
|
||||
|
||||
In PuTTY, you can achieve connection sharing in the @option{Connection/SSH}
|
||||
entry, enabling the @option{Share SSH connections if possible} option.
|
||||
|
||||
|
||||
@subsection Configure direct copying between two remote servers
|
||||
|
||||
@vindex tramp-use-scp-direct-remote-copying
|
||||
@value{tramp} uses a temporary local copy when copying two files
|
||||
between different remote hosts via external methods. This behavior is
|
||||
due to authentication problems @value{tramp} cannot handle
|
||||
sufficiently. However, for @option{scp} connections this can be
|
||||
changed. When a file shall be copied between two different remote
|
||||
hosts @samp{source} and @samp{target}, and
|
||||
|
||||
@itemize @minus
|
||||
@item
|
||||
Variable @code{tramp-use-scp-direct-remote-copying} is non-@code{nil},
|
||||
|
||||
@item
|
||||
Remote host @samp{source} doesn't use the @option{RemoteCommand}
|
||||
option in @file{~/.ssh/config},
|
||||
|
||||
@item
|
||||
Remote host @samp{target} shows the same host key when seen from the
|
||||
local host and from host @samp{source}, and
|
||||
|
||||
@item
|
||||
@command{scp} running on host @samp{source} can authenticate to host
|
||||
@samp{target} without requiring a password,
|
||||
@end itemize
|
||||
|
||||
@noindent
|
||||
@value{tramp} applies direct remote copying between hosts
|
||||
@samp{source} and @samp{target} like
|
||||
|
||||
@example
|
||||
scp -p -T -R -q -r source:/path/to/file target:/path/to/another/file
|
||||
@end example
|
||||
|
||||
This protects also your local temporary directory from overrun when
|
||||
copying large files.
|
||||
|
||||
If these conditions do not apply, and
|
||||
@code{tramp-use-scp-direct-remote-copying} is non-@code{nil}, the
|
||||
option @samp{-3} is used instead of @samp{-R}.
|
||||
|
||||
@c FIXME
|
||||
When @value{tramp} uses direct remote copying, password caches are not
|
||||
consulted.
|
||||
|
||||
|
||||
@subsection Issues with Cygwin ssh
|
||||
@cindex cygwin, issues
|
||||
|
||||
This section is incomplete. Please share your solutions.
|
||||
|
||||
@cindex method @option{sshx} with cygwin
|
||||
@cindex @option{sshx} method with cygwin
|
||||
|
||||
Cygwin's @command{ssh} works only with a Cygwin version of Emacs. To
|
||||
check for compatibility: type @kbd{M-x eshell @key{RET}}, and start
|
||||
@kbd{ssh test.host @key{RET}}. Incompatibilities trigger this
|
||||
message:
|
||||
|
||||
@example
|
||||
Pseudo-terminal will not be allocated because stdin is not a terminal.
|
||||
@end example
|
||||
|
||||
Some older versions of Cygwin's @command{ssh} work with the
|
||||
@option{sshx} access method. Consult Cygwin's FAQ at
|
||||
@uref{https://cygwin.com/faq/} for details.
|
||||
|
||||
@cindex cygwin and @command{fakecygpty}
|
||||
@cindex @command{fakecygpty} and cygwin
|
||||
|
||||
On @uref{https://www.emacswiki.org/emacs/SshWithNTEmacs, the Emacs
|
||||
Wiki} it is explained how to use the helper program
|
||||
@command{fakecygpty} to fix this problem.
|
||||
|
||||
@cindex method @option{scpx} with cygwin
|
||||
@cindex @option{scpx} method with cygwin
|
||||
|
||||
When using the @option{scpx} access method, Emacs may call
|
||||
@command{scp} with MS Windows file naming, such as @file{c:/foo}. But
|
||||
the version of @command{scp} that is installed with Cygwin does not
|
||||
know about MS Windows file naming, which causes it to incorrectly look
|
||||
for a host named @samp{c}.
|
||||
|
||||
A workaround: write a wrapper script for @option{scp} to convert
|
||||
Windows file names to Cygwin file names.
|
||||
|
||||
@cindex cygwin and @command{ssh-agent}
|
||||
@cindex @env{SSH_AUTH_SOCK} and emacs on ms windows
|
||||
@vindex SSH_AUTH_SOCK@r{, environment variable}
|
||||
|
||||
When using the @command{ssh-agent} on MS Windows for password-less
|
||||
interaction, @option{ssh} methods depend on the environment variable
|
||||
@env{SSH_AUTH_SOCK}. But this variable is not set when Emacs is
|
||||
started from a Desktop shortcut and authentication fails.
|
||||
|
||||
One workaround is to use an MS Windows based SSH Agent, such as
|
||||
@command{Pageant}. It is part of the PuTTY Suite of tools.
|
||||
|
||||
The fallback is to start Emacs from a shell.
|
||||
|
||||
|
||||
@node FUSE setup
|
||||
@section @acronym{FUSE} setup hints
|
||||
|
||||
|
@ -2828,10 +3042,10 @@ Example:
|
|||
The backup file name of
|
||||
@file{@trampfn{su,root@@localhost,/etc/secretfile}} would be
|
||||
@ifset unified
|
||||
@file{@trampfn{su,root@@localhost,~/.emacs.d/backups/!su:root@@localhost:!etc!secretfile~}}
|
||||
@file{@trampfn{su,root@@localhost,~/.emacs.d/backups/!su:root@@localhost:!etc!secretfile~}}.
|
||||
@end ifset
|
||||
@ifset separate
|
||||
@file{@trampfn{su,root@@localhost,~/.emacs.d/backups/![su!root@@localhost]!etc!secretfile~}}
|
||||
@file{@trampfn{su,root@@localhost,~/.emacs.d/backups/![su!root@@localhost]!etc!secretfile~}}.
|
||||
@end ifset
|
||||
|
||||
@vindex auto-save-file-name-transforms
|
||||
|
@ -2985,62 +3199,6 @@ subdirectories will remain encrypted.
|
|||
@end deffn
|
||||
|
||||
|
||||
@node Windows setup hints
|
||||
@section Issues with Cygwin ssh
|
||||
@cindex cygwin, issues
|
||||
|
||||
This section is incomplete. Please share your solutions.
|
||||
|
||||
@cindex method @option{sshx} with cygwin
|
||||
@cindex @option{sshx} method with cygwin
|
||||
|
||||
Cygwin's @command{ssh} works only with a Cygwin version of Emacs. To
|
||||
check for compatibility: type @kbd{M-x eshell @key{RET}}, and start
|
||||
@kbd{ssh test.host @key{RET}}. Incompatibilities trigger this
|
||||
message:
|
||||
|
||||
@example
|
||||
Pseudo-terminal will not be allocated because stdin is not a terminal.
|
||||
@end example
|
||||
|
||||
Some older versions of Cygwin's @command{ssh} work with the
|
||||
@option{sshx} access method. Consult Cygwin's FAQ at
|
||||
@uref{https://cygwin.com/faq/} for details.
|
||||
|
||||
@cindex cygwin and @command{fakecygpty}
|
||||
@cindex @command{fakecygpty} and cygwin
|
||||
|
||||
On @uref{https://www.emacswiki.org/emacs/SshWithNTEmacs, the Emacs
|
||||
Wiki} it is explained how to use the helper program
|
||||
@command{fakecygpty} to fix this problem.
|
||||
|
||||
@cindex method @option{scpx} with cygwin
|
||||
@cindex @option{scpx} method with cygwin
|
||||
|
||||
When using the @option{scpx} access method, Emacs may call
|
||||
@command{scp} with MS Windows file naming, such as @file{c:/foo}. But
|
||||
the version of @command{scp} that is installed with Cygwin does not
|
||||
know about MS Windows file naming, which causes it to incorrectly look
|
||||
for a host named @samp{c}.
|
||||
|
||||
A workaround: write a wrapper script for @option{scp} to convert
|
||||
Windows file names to Cygwin file names.
|
||||
|
||||
@cindex cygwin and @command{ssh-agent}
|
||||
@cindex @env{SSH_AUTH_SOCK} and emacs on ms windows
|
||||
@vindex SSH_AUTH_SOCK@r{, environment variable}
|
||||
|
||||
When using the @command{ssh-agent} on MS Windows for password-less
|
||||
interaction, @option{ssh} methods depend on the environment variable
|
||||
@env{SSH_AUTH_SOCK}. But this variable is not set when Emacs is
|
||||
started from a Desktop shortcut and authentication fails.
|
||||
|
||||
One workaround is to use an MS Windows based SSH Agent, such as
|
||||
Pageant. It is part of the Putty Suite of tools.
|
||||
|
||||
The fallback is to start Emacs from a shell.
|
||||
|
||||
|
||||
@node Usage
|
||||
@chapter Using @value{tramp}
|
||||
@cindex using @value{tramp}
|
||||
|
@ -3085,23 +3243,23 @@ is a feature of Emacs that may cause missed prompts when using
|
|||
on the remote host @var{host}, using the method @var{method}.
|
||||
|
||||
@table @file
|
||||
@item @value{prefix}ssh@value{postfixhop}melancholia@value{postfix}.emacs
|
||||
@item @trampfn{ssh,melancholia,.emacs}
|
||||
For the file @file{.emacs} located in the home directory, on the host
|
||||
@code{melancholia}, using method @code{ssh}.
|
||||
|
||||
@item @value{prefix}ssh@value{postfixhop}melancholia.danann.net@value{postfix}.emacs
|
||||
@item @trampfn{ssh,melancholia.danann.net,.emacs}
|
||||
For the file @file{.emacs} specified using the fully qualified domain name of
|
||||
the host.
|
||||
|
||||
@item @value{prefix}ssh@value{postfixhop}melancholia@value{postfix}~/.emacs
|
||||
@item @trampfn{ssh,melancholia,~/.emacs}
|
||||
For the file @file{.emacs} specified using the @file{~}, which is expanded.
|
||||
|
||||
@item @value{prefix}ssh@value{postfixhop}melancholia@value{postfix}~daniel/.emacs
|
||||
@item @trampfn{ssh,melancholia,~daniel/.emacs}
|
||||
For the file @file{.emacs} located in @code{daniel}'s home directory
|
||||
on the host, @code{melancholia}. The @file{~<user>} construct is
|
||||
expanded to the home directory of that user on the remote host.
|
||||
|
||||
@item @value{prefix}ssh@value{postfixhop}melancholia@value{postfix}/etc/squid.conf
|
||||
@item @trampfn{ssh,melancholia,/etc/squid.conf}
|
||||
For the file @file{/etc/squid.conf} on the host @code{melancholia}.
|
||||
|
||||
@end table
|
||||
|
@ -3115,12 +3273,9 @@ brackets @file{@value{ipv6prefix}} and @file{@value{ipv6postfix}}.
|
|||
@end ifset
|
||||
|
||||
By default, @value{tramp} will use the current local user name as the
|
||||
remote user name for log in to the remote host. Specifying a different
|
||||
name using the proper syntax will override this default behavior:
|
||||
|
||||
@example
|
||||
@trampfn{method,user@@host,path/to/file}
|
||||
@end example
|
||||
remote user name for log in to the remote host. Specifying a
|
||||
different name using the proper syntax will override this default
|
||||
behavior: @file{@trampfn{method,user@@host,path/to/file}}.
|
||||
|
||||
@file{@trampfn{ssh,daniel@@melancholia,.emacs}} is for file
|
||||
@file{.emacs} in @code{daniel}'s home directory on the host,
|
||||
|
@ -3316,8 +3471,9 @@ remote host name and file name. For example, hopping over a single
|
|||
proxy @samp{bird@@bastion} to a remote file on @samp{you@@remotehost}:
|
||||
|
||||
@example
|
||||
@c @kbd{C-x C-f @trampfn{ssh@value{postfixhop}bird@@bastion|ssh,you,remotehost,/path} @key{RET}}
|
||||
@kbd{C-x C-f @value{prefix}ssh@value{postfixhop}bird@@bastion|ssh@value{postfixhop}you@@remotehost@value{postfix}/path @key{RET}}
|
||||
@c @kbd{C-x C-f @trampfn{ssh@value{postfixhop}bird@@bastion|ssh,you@@remotehost,/path} @key{RET}}
|
||||
@kbd{C-x C-f @value{prefix}ssh@value{postfixhop}bird@@bastion|@c
|
||||
ssh@value{postfixhop}you@@remotehost@value{postfix}/path @key{RET}}
|
||||
@end example
|
||||
|
||||
Each involved method must be an inline method (@pxref{Inline methods}).
|
||||
|
@ -3345,12 +3501,12 @@ Ad-hoc proxies can take patterns @code{%h} or @code{%u} like in
|
|||
@code{tramp-default-proxies-alist}. The following file name expands
|
||||
to user @samp{root} on host @samp{remotehost}, starting with an
|
||||
@option{ssh} session on host @samp{remotehost}:
|
||||
@samp{@value{prefix}ssh@value{postfixhop}%h|su@value{postfixhop}remotehost@value{postfix}}.
|
||||
@samp{@trampfn{ssh@value{postfixhop}%h|su,remotehost,}}.
|
||||
|
||||
On the other hand, if a trailing hop does not specify a host name,
|
||||
the host name of the previous hop is reused. Therefore, the following
|
||||
On the other hand, if a trailing hop does not specify a host name, the
|
||||
host name of the previous hop is reused. Therefore, the following
|
||||
file name is equivalent to the previous example:
|
||||
@samp{@value{prefix}ssh@value{postfixhop}remotehost|su@value{postfixhop}@value{postfix}}.
|
||||
@samp{@trampfn{ssh@value{postfixhop}remotehost|su,,}}.
|
||||
|
||||
|
||||
@node Remote processes
|
||||
|
@ -3971,7 +4127,9 @@ would trigger renaming of buffer file names on @samp{badhost} to
|
|||
@samp{goodhost}, including changing the directory name.
|
||||
|
||||
@lisp
|
||||
("@trampfn{ssh,.+\\\\.company\\\\.org,}" . "@value{prefix}ssh@value{postfixhop}multi.hop|ssh@value{postfixhop}%h@value{postfix}")
|
||||
("@trampfn{ssh,.+\\\\.company\\\\.org,}" @c
|
||||
. "@value{prefix}ssh@value{postfixhop}multi.hop|@c
|
||||
ssh@value{postfixhop}%h@value{postfix}")
|
||||
@end lisp
|
||||
|
||||
routes all connections to a host in @samp{company.org} via
|
||||
|
@ -4231,7 +4389,8 @@ It is even possible to access file archives in file archives, as
|
|||
(progn
|
||||
(url-handler-mode 1)
|
||||
(find-file
|
||||
"https://ftp.debian.org/debian/pool/main/c/coreutils/coreutils_8.28-1_amd64.deb/control.tar.gz/control"))
|
||||
"https://ftp.debian.org/debian/pool/main/c/coreutils/\
|
||||
coreutils_8.28-1_amd64.deb/control.tar.gz/control"))
|
||||
@end group
|
||||
@end lisp
|
||||
|
||||
|
@ -4537,97 +4696,6 @@ In order to disable those optimizations, set user option
|
|||
@code{tramp-local-host-regexp} to @code{nil}.
|
||||
|
||||
|
||||
@item
|
||||
@value{tramp} does not recognize if a @command{ssh} session hangs
|
||||
|
||||
@vindex ServerAliveInterval@r{, ssh option}
|
||||
@command{ssh} sessions on the local host hang when the network is
|
||||
down. @value{tramp} cannot safely detect such hangs. The network
|
||||
configuration for @command{ssh} can be configured to kill such hangs
|
||||
with the following command in the @file{~/.ssh/config}:
|
||||
|
||||
@example
|
||||
@group
|
||||
Host *
|
||||
ServerAliveInterval 5
|
||||
@end group
|
||||
@end example
|
||||
|
||||
|
||||
@item
|
||||
@value{tramp} does not use default @command{ssh} @option{ControlPath}
|
||||
|
||||
@vindex ControlPath@r{, ssh option}
|
||||
@vindex ControlPersist@r{, ssh option}
|
||||
@value{tramp} overwrites @option{ControlPath} settings when initiating
|
||||
@command{ssh} sessions. @value{tramp} does this to fend off a stall
|
||||
if a master session opened outside the Emacs session is no longer
|
||||
open. That is why @value{tramp} prompts for the password again even
|
||||
if there is an @command{ssh} already open.
|
||||
|
||||
@vindex tramp-ssh-controlmaster-options
|
||||
Some @command{ssh} versions support a @option{ControlPersist} option,
|
||||
which allows you to set the @option{ControlPath} provided the variable
|
||||
@code{tramp-ssh-controlmaster-options} is customized as follows:
|
||||
|
||||
@lisp
|
||||
@group
|
||||
(customize-set-variable
|
||||
'tramp-ssh-controlmaster-options
|
||||
(concat
|
||||
"-o ControlPath=/tmp/ssh-ControlPath-%%r@@%%h:%%p "
|
||||
"-o ControlMaster=auto -o ControlPersist=yes"))
|
||||
@end group
|
||||
@end lisp
|
||||
|
||||
Note how @samp{%r}, @samp{%h} and @samp{%p} must be encoded as
|
||||
@samp{%%r}, @samp{%%h} and @samp{%%p}.
|
||||
|
||||
@vindex tramp-use-ssh-controlmaster-options
|
||||
If the @file{~/.ssh/config} file is configured appropriately for the
|
||||
above behavior, then any changes to @command{ssh} can be suppressed
|
||||
with this @code{nil} setting:
|
||||
|
||||
@lisp
|
||||
(customize-set-variable 'tramp-use-ssh-controlmaster-options nil)
|
||||
@end lisp
|
||||
|
||||
@vindex ProxyCommand@r{, ssh option}
|
||||
@vindex ProxyJump@r{, ssh option}
|
||||
This should also be set to @code{nil} if you use the
|
||||
@option{ProxyCommand} or @option{ProxyJump} options in your
|
||||
@command{ssh} configuration.
|
||||
|
||||
On MS Windows, @code{tramp-use-ssh-controlmaster-options} is set to
|
||||
@code{nil} by default, because the MS Windows and MSYS2
|
||||
implementations of @command{OpenSSH} do not support this option properly.
|
||||
|
||||
|
||||
@item
|
||||
On multi-hop connections, @value{tramp} does not use @command{ssh}
|
||||
@option{ControlMaster}
|
||||
|
||||
In order to use the @option{ControlMaster} option, @value{tramp} must
|
||||
check whether the @command{ssh} client supports this option. This is
|
||||
only possible on the local host, for the first hop. @value{tramp}
|
||||
does not use this option on proxy hosts.
|
||||
|
||||
If you want to use this option also for the other hops, you must
|
||||
configure @file{~/.ssh/config} on the proxy host:
|
||||
|
||||
@example
|
||||
@group
|
||||
Host *
|
||||
ControlMaster auto
|
||||
ControlPath tramp.%C
|
||||
ControlPersist no
|
||||
@end group
|
||||
@end example
|
||||
|
||||
Check the @samp{ssh_config(5)} man page whether these options are
|
||||
supported on your proxy host.
|
||||
|
||||
|
||||
@item
|
||||
Does @value{tramp} support @acronym{SSH} security keys?
|
||||
|
||||
|
@ -5075,7 +5143,8 @@ Why saved multi-hop file names do not work in a new Emacs session?
|
|||
When saving ad-hoc multi-hop @value{tramp} file names (@pxref{Ad-hoc
|
||||
multi-hops}) via bookmarks, recent files, filecache, bbdb, or another
|
||||
package, use the full ad-hoc file name including all hops, like
|
||||
@file{@trampfn{ssh,bird@@bastion|ssh@value{postfixhop}news.my.domain,/opt/news/etc}}.
|
||||
@file{@trampfn{ssh,bird@@bastion|ssh@value{postfixhop}@c
|
||||
news.my.domain,/opt/news/etc}}.
|
||||
|
||||
Alternatively, when saving abbreviated multi-hop file names
|
||||
@file{@trampfn{ssh,news@@news.my.domain,/opt/news/etc}}, the user
|
||||
|
@ -5384,7 +5453,7 @@ bind it to non-@code{nil} value.
|
|||
Keeping a local cache of remote file attributes in sync with the
|
||||
remote host is a time-consuming operation. Flushing and re-querying
|
||||
these attributes can tax @value{tramp} to a grinding halt on busy
|
||||
remote servers.
|
||||
remote hosts.
|
||||
|
||||
To get around these types of slow-downs in @value{tramp}'s
|
||||
responsiveness, set the @code{process-file-side-effects} to @code{nil}
|
||||
|
@ -5539,6 +5608,8 @@ function call traces are written to the buffer @file{*trace-output*}.
|
|||
@c
|
||||
@c * Say something about the .login and .profile files of the remote
|
||||
@c shells.
|
||||
@c
|
||||
@c * Explain how tramp.el works in principle: open a shell on a remote
|
||||
@c host and then send commands to it.
|
||||
@c
|
||||
@c * Consistent small or capitalized words especially in menus.
|
||||
|
|
58
etc/NEWS
58
etc/NEWS
|
@ -72,8 +72,8 @@ work on any underlying window system supported by GDK, such as
|
|||
Wayland and Broadway.
|
||||
|
||||
---
|
||||
** The docstrings of preloaded files are not in 'etc/DOC' any more.
|
||||
Instead, they're fetched as needed from the corresponding '.elc' file,
|
||||
** The docstrings of preloaded files are not in "etc/DOC" any more.
|
||||
Instead, they're fetched as needed from the corresponding ".elc" file,
|
||||
as was already the case for all the non-preloaded files.
|
||||
|
||||
|
||||
|
@ -94,10 +94,10 @@ time.
|
|||
|
||||
---
|
||||
** Support for old EIEIO functions is not autoloaded any more.
|
||||
You need an explicit (require 'eieio-compat) to use 'defmethod'
|
||||
and 'defgeneric' (which have been made obsolete in Emacs-25 with
|
||||
You need an explicit '(require 'eieio-compat)' to use 'defmethod'
|
||||
and 'defgeneric' (which have been made obsolete in Emacs 25.1 with
|
||||
'cl-defmethod' and 'cl-defgeneric').
|
||||
Similarly you might need to (require 'eieio-compat) before loading
|
||||
Similarly you might need to '(require 'eieio-compat)' before loading
|
||||
files that were compiled with an old EIEIO (Emacs<25).
|
||||
|
||||
---
|
||||
|
@ -260,13 +260,13 @@ These will take you (respectively) to the next and previous "page".
|
|||
** Outline Mode
|
||||
|
||||
*** Support for customizing the default visibility state of headings.
|
||||
Customize the option 'outline-default-state' to define what headings
|
||||
will be visible after Outline mode is turned on. When equal to a
|
||||
number, the option 'outline-default-rules' determines the visibility
|
||||
of the subtree starting at the corresponding level. Values are
|
||||
provided to control showing a heading subtree depending on whether the
|
||||
heading matches a regexp, or on whether its subtree has long lines or
|
||||
is itself too long.
|
||||
Customize the user option 'outline-default-state' to define what
|
||||
headings will be visible after Outline mode is turned on. When equal
|
||||
to a number, the user option 'outline-default-rules' determines the
|
||||
visibility of the subtree starting at the corresponding level. Values
|
||||
are provided to control showing a heading subtree depending on whether
|
||||
the heading matches a regexp, or on whether its subtree has long lines
|
||||
or is itself too long.
|
||||
|
||||
** Outline Minor Mode
|
||||
|
||||
|
@ -414,15 +414,15 @@ received.
|
|||
|
||||
** Minibuffer and Completions
|
||||
|
||||
*** The *Completions* buffer can now be automatically selected.
|
||||
To enable this behavior, customize the option 'completion-auto-select'
|
||||
to t. Then pressing TAB will switch to the *Completions* buffer when
|
||||
it pops up that buffer.
|
||||
*** The "*Completions*" buffer can now be automatically selected.
|
||||
To enable this behavior, customize the user option
|
||||
'completion-auto-select' to t. Then pressing 'TAB' will switch to the
|
||||
"*Completions*" buffer when it pops up that buffer.
|
||||
|
||||
*** New user option 'completion-wrap-movement'.
|
||||
When non-nil, the commands 'next-completion' and 'previous-completion'
|
||||
automatically wrap around on reaching the beginning or the end of
|
||||
the *Completions* buffer.
|
||||
the "*Completions*" buffer.
|
||||
|
||||
** Isearch and Replace
|
||||
|
||||
|
@ -484,7 +484,7 @@ If non-nil, 'C-c C-a' will put attached files at the end of the message.
|
|||
---
|
||||
*** Message Mode now supports image yanking.
|
||||
|
||||
---
|
||||
+++
|
||||
*** New user option 'message-server-alist'.
|
||||
This controls automatic insertion of the "X-Message-SMTP-Method"
|
||||
header before sending a message.
|
||||
|
@ -836,6 +836,12 @@ When calling 'abbreviate-file-name' on a Tramp filename, the result
|
|||
will abbreviate the user's home directory, for example by abbreviating
|
||||
"/ssh:user@host:/home/user" to "/ssh:user@host:~".
|
||||
|
||||
+++
|
||||
*** New user option 'tramp-use-scp-direct-remote-copying'.
|
||||
When set to non-nil, Tramp does not copy files between two remote
|
||||
hosts via a local copy in its temporary directory, but let the 'scp'
|
||||
command do this job.
|
||||
|
||||
** Browse URL
|
||||
|
||||
---
|
||||
|
@ -991,7 +997,7 @@ read back by the Emacs Lisp reader.
|
|||
This variable allows changing how Emacs prints unreadable objects.
|
||||
|
||||
---
|
||||
** The variable 'polling-period' now accepts floating point values.
|
||||
** The user option 'polling-period' now accepts floating point values.
|
||||
This means Emacs can now poll for input during Lisp execution more
|
||||
frequently than once in a second.
|
||||
|
||||
|
@ -1039,7 +1045,7 @@ wheel on some mice, or when the user's finger moves off the touchpad.
|
|||
|
||||
+++
|
||||
** New event type 'pinch'.
|
||||
This event is sent when a user peforms a pinch gesture on a touchpad,
|
||||
This event is sent when a user performs a pinch gesture on a touchpad,
|
||||
which is comprised of placing two fingers on the touchpad and moving
|
||||
them towards or away from each other.
|
||||
|
||||
|
@ -1199,14 +1205,14 @@ This can be used to check whether a specific font has a glyph for a
|
|||
character.
|
||||
|
||||
+++
|
||||
** 'window-text-pixel-size' now accepts a new argument 'ignore-line-at-end'.
|
||||
** 'window-text-pixel-size' now accepts a new argument IGNORE-LINE-AT-END.
|
||||
This controls whether or not the last screen line of the text being
|
||||
measured will be counted for the purpose of calculating the text
|
||||
dimensions.
|
||||
|
||||
+++
|
||||
** 'window-text-pixel-size' understands a new meaning of 'from'.
|
||||
Specifying a cons as the from argument allows to start measuring text
|
||||
** 'window-text-pixel-size' understands a new meaning of FROM.
|
||||
Specifying a cons as the FROM argument allows to start measuring text
|
||||
from a specified amount of pixels above or below a position.
|
||||
|
||||
---
|
||||
|
@ -1383,9 +1389,9 @@ cookies set by web pages on disk.
|
|||
This variable is bound to t during the preparation of a "*Help*" buffer.
|
||||
|
||||
+++
|
||||
** Timestamps like (1 . 1000) now work without warnings being generated.
|
||||
For example, (time-add nil '(1 . 1000)) no longer warns that the
|
||||
(1 . 1000) acts like (1000 . 1000000). This warning, which was a
|
||||
** Timestamps like '(1 . 1000)' now work without warnings being generated.
|
||||
For example, '(time-add nil '(1 . 1000))' no longer warns that the
|
||||
'(1 . 1000)' acts like '(1000 . 1000000)'. This warning, which was a
|
||||
temporary transition aid for Emacs 27, has served its purpose.
|
||||
|
||||
+++
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
(declare-function dired-compress-file "dired-aux")
|
||||
(declare-function dired-remove-file "dired-aux")
|
||||
(defvar dired-compress-file-suffixes)
|
||||
;; Added in Emacs 28.1.
|
||||
(defvar process-file-return-signal-string)
|
||||
(defvar vc-handled-backends)
|
||||
(defvar vc-bzr-program)
|
||||
|
@ -136,6 +137,12 @@ be auto-detected by Tramp.
|
|||
|
||||
The string is used in `tramp-methods'.")
|
||||
|
||||
(defcustom tramp-use-scp-direct-remote-copying nil
|
||||
"Whether to use direct copying between two remote hosts."
|
||||
:group 'tramp
|
||||
:version "29.1"
|
||||
:type 'boolean)
|
||||
|
||||
;; Initialize `tramp-methods' with the supported methods.
|
||||
;;;###tramp-autoload
|
||||
(tramp--with-startup
|
||||
|
@ -172,7 +179,7 @@ The string is used in `tramp-methods'.")
|
|||
(tramp-remote-shell-args ("-c"))
|
||||
(tramp-copy-program "scp")
|
||||
(tramp-copy-args (("-P" "%p") ("-p" "%k")
|
||||
("%x") ("-q") ("-r") ("%c")))
|
||||
("%x") ("%y") ("-q") ("-r") ("%c")))
|
||||
(tramp-copy-keep-date t)
|
||||
(tramp-copy-recursive t)))
|
||||
(add-to-list 'tramp-methods
|
||||
|
@ -188,7 +195,7 @@ The string is used in `tramp-methods'.")
|
|||
(tramp-remote-shell-args ("-c"))
|
||||
(tramp-copy-program "scp")
|
||||
(tramp-copy-args (("-P" "%p") ("-p" "%k")
|
||||
("%x") ("-q") ("-r") ("%c")))
|
||||
("%x") ("%y") ("-q") ("-r") ("%c")))
|
||||
(tramp-copy-keep-date t)
|
||||
(tramp-copy-recursive t)))
|
||||
(add-to-list 'tramp-methods
|
||||
|
@ -2240,200 +2247,210 @@ the uid and gid from FILENAME."
|
|||
(op filename newname ok-if-already-exists keep-date)
|
||||
"Invoke `scp' program to copy.
|
||||
The method used must be an out-of-band method."
|
||||
(let* ((t1 (tramp-tramp-file-p filename))
|
||||
(t2 (tramp-tramp-file-p newname))
|
||||
(orig-vec (tramp-dissect-file-name (if t1 filename newname)))
|
||||
(let* ((v1 (and (tramp-tramp-file-p filename)
|
||||
(tramp-dissect-file-name filename)))
|
||||
(v2 (and (tramp-tramp-file-p newname)
|
||||
(tramp-dissect-file-name newname)))
|
||||
(v (or v1 v2))
|
||||
copy-program copy-args copy-env copy-keep-date listener spec
|
||||
options source target remote-copy-program remote-copy-args p)
|
||||
|
||||
(with-parsed-tramp-file-name (if t1 filename newname) nil
|
||||
(if (and t1 t2)
|
||||
(if (and v1 v2 (zerop (length (tramp-scp-direct-remote-copying v1 v2))))
|
||||
|
||||
;; Both are Tramp files. We shall optimize it when the
|
||||
;; methods for FILENAME and NEWNAME are the same.
|
||||
(let* ((dir-flag (file-directory-p filename))
|
||||
(tmpfile (tramp-compat-make-temp-file localname dir-flag)))
|
||||
(if dir-flag
|
||||
(setq tmpfile
|
||||
(expand-file-name
|
||||
(file-name-nondirectory newname) tmpfile)))
|
||||
(unwind-protect
|
||||
(progn
|
||||
(tramp-do-copy-or-rename-file-out-of-band
|
||||
op filename tmpfile ok-if-already-exists keep-date)
|
||||
(tramp-do-copy-or-rename-file-out-of-band
|
||||
'rename tmpfile newname ok-if-already-exists keep-date))
|
||||
;; Save exit.
|
||||
(ignore-errors
|
||||
(if dir-flag
|
||||
(delete-directory
|
||||
(expand-file-name ".." tmpfile) 'recursive)
|
||||
(delete-file tmpfile)))))
|
||||
|
||||
;; Check which ones of source and target are Tramp files.
|
||||
(setq source (funcall
|
||||
(if (and (string-equal method "rsync")
|
||||
(file-directory-p filename)
|
||||
(not (file-exists-p newname)))
|
||||
#'file-name-as-directory
|
||||
#'identity)
|
||||
(if t1
|
||||
(tramp-make-copy-program-file-name v)
|
||||
(tramp-compat-file-name-unquote filename)))
|
||||
target (if t2
|
||||
(tramp-make-copy-program-file-name v)
|
||||
(tramp-compat-file-name-unquote newname)))
|
||||
|
||||
;; Check for user. There might be an interactive setting.
|
||||
(setq user (or (tramp-file-name-user v)
|
||||
(tramp-get-connection-property v "login-as" nil)))
|
||||
|
||||
;; Check for listener port.
|
||||
(when (tramp-get-method-parameter v 'tramp-remote-copy-args)
|
||||
(setq listener (number-to-string (+ 50000 (random 10000))))
|
||||
(while
|
||||
(zerop (tramp-call-process v "nc" nil nil nil "-z" host listener))
|
||||
(setq listener (number-to-string (+ 50000 (random 10000))))))
|
||||
|
||||
;; Compose copy command.
|
||||
(setq options
|
||||
(format-spec
|
||||
(tramp-ssh-controlmaster-options v)
|
||||
(format-spec-make
|
||||
?t (tramp-get-connection-property
|
||||
(tramp-get-connection-process v) "temp-file" "")))
|
||||
spec (list
|
||||
?h (or host "") ?u (or user "") ?p (or port "")
|
||||
?r listener ?c options ?k (if keep-date " " "")
|
||||
?n (concat "2>" (tramp-get-remote-null-device v))
|
||||
?x (tramp-scp-strict-file-name-checking v))
|
||||
copy-program (tramp-get-method-parameter v 'tramp-copy-program)
|
||||
copy-keep-date (tramp-get-method-parameter
|
||||
v 'tramp-copy-keep-date)
|
||||
copy-args
|
||||
;; " " has either been a replacement of "%k" (when
|
||||
;; 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 (tramp-compat-string-search " " 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)
|
||||
remote-copy-args
|
||||
(apply #'tramp-expand-args v 'tramp-remote-copy-args spec))
|
||||
|
||||
;; Check for local copy program.
|
||||
(unless (executable-find copy-program)
|
||||
(tramp-error
|
||||
v 'file-error "Cannot find local copy program: %s" copy-program))
|
||||
|
||||
;; Install listener on the remote side. The prompt must be
|
||||
;; consumed later on, when the process does not listen anymore.
|
||||
(when remote-copy-program
|
||||
(unless (with-tramp-connection-property
|
||||
v (concat "remote-copy-program-" remote-copy-program)
|
||||
(tramp-find-executable
|
||||
v remote-copy-program (tramp-get-remote-path v)))
|
||||
(tramp-error
|
||||
v 'file-error
|
||||
"Cannot find remote listener: %s" remote-copy-program))
|
||||
(setq remote-copy-program
|
||||
(mapconcat
|
||||
#'identity
|
||||
(append
|
||||
(list remote-copy-program) remote-copy-args
|
||||
(list (if t1 (concat "<" source) (concat ">" target)) "&"))
|
||||
" "))
|
||||
(tramp-send-command v remote-copy-program)
|
||||
(with-timeout
|
||||
(60 (tramp-error
|
||||
v 'file-error
|
||||
"Listener process not running on remote host: `%s'"
|
||||
remote-copy-program))
|
||||
(tramp-send-command v (format "netstat -l | grep -q :%s" listener))
|
||||
(while (not (tramp-send-command-and-check v nil))
|
||||
(tramp-send-command
|
||||
v (format "netstat -l | grep -q :%s" listener)))))
|
||||
|
||||
(with-temp-buffer
|
||||
;; Both are Tramp files. We cannot use direct remote copying.
|
||||
(let* ((dir-flag (file-directory-p filename))
|
||||
(tmpfile (tramp-compat-make-temp-file
|
||||
(tramp-file-name-localname v1) dir-flag)))
|
||||
(if dir-flag
|
||||
(setq tmpfile
|
||||
(expand-file-name
|
||||
(file-name-nondirectory newname) tmpfile)))
|
||||
(unwind-protect
|
||||
;; The default directory must be remote.
|
||||
(let ((default-directory
|
||||
(file-name-directory (if t1 filename newname)))
|
||||
(process-environment (copy-sequence process-environment)))
|
||||
;; Set the transfer process properties.
|
||||
(tramp-set-connection-property
|
||||
v "process-name" (buffer-name (current-buffer)))
|
||||
(tramp-set-connection-property
|
||||
v "process-buffer" (current-buffer))
|
||||
(when copy-env
|
||||
(tramp-message
|
||||
orig-vec 6 "%s=\"%s\""
|
||||
(car copy-env) (string-join (cdr copy-env) " "))
|
||||
(setenv (car copy-env) (string-join (cdr copy-env) " ")))
|
||||
(setq
|
||||
copy-args
|
||||
(append
|
||||
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.
|
||||
p (let ((default-directory tramp-compat-temporary-file-directory))
|
||||
(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)
|
||||
(progn
|
||||
(tramp-do-copy-or-rename-file-out-of-band
|
||||
op filename tmpfile ok-if-already-exists keep-date)
|
||||
(tramp-do-copy-or-rename-file-out-of-band
|
||||
'rename tmpfile newname ok-if-already-exists keep-date))
|
||||
;; Save exit.
|
||||
(ignore-errors
|
||||
(if dir-flag
|
||||
(delete-directory
|
||||
(expand-file-name ".." tmpfile) 'recursive)
|
||||
(delete-file tmpfile)))))
|
||||
|
||||
;; 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)))
|
||||
;; Check which ones of source and target are Tramp files.
|
||||
(setq source (funcall
|
||||
(if (and (string-equal (tramp-file-name-method v) "rsync")
|
||||
(file-directory-p filename)
|
||||
(not (file-exists-p newname)))
|
||||
#'file-name-as-directory
|
||||
#'identity)
|
||||
(if v1
|
||||
(tramp-make-copy-program-file-name v1)
|
||||
(tramp-compat-file-name-unquote filename)))
|
||||
target (if v2
|
||||
(tramp-make-copy-program-file-name v2)
|
||||
(tramp-compat-file-name-unquote newname)))
|
||||
|
||||
;; Reset the transfer process properties.
|
||||
(tramp-flush-connection-property v "process-name")
|
||||
(tramp-flush-connection-property v "process-buffer")
|
||||
;; Clear the remote prompt.
|
||||
(when (and remote-copy-program
|
||||
(not (tramp-send-command-and-check v nil)))
|
||||
;; Houston, we have a problem! Likely, the listener is
|
||||
;; still running, so let's clear everything (but the
|
||||
;; cached password).
|
||||
(tramp-cleanup-connection v 'keep-debug 'keep-password))))
|
||||
;; Check for listener port.
|
||||
(when (tramp-get-method-parameter v 'tramp-remote-copy-args)
|
||||
(setq listener (number-to-string (+ 50000 (random 10000))))
|
||||
(while
|
||||
(zerop (tramp-call-process
|
||||
v "nc" nil nil nil "-z" (tramp-file-name-host v) listener))
|
||||
(setq listener (number-to-string (+ 50000 (random 10000))))))
|
||||
|
||||
;; Handle KEEP-DATE argument.
|
||||
(when (and keep-date (not copy-keep-date))
|
||||
(tramp-compat-set-file-times
|
||||
newname
|
||||
(file-attribute-modification-time (file-attributes filename))
|
||||
(unless ok-if-already-exists 'nofollow)))
|
||||
;; Compose copy command.
|
||||
(setq options
|
||||
(format-spec
|
||||
(tramp-ssh-controlmaster-options v)
|
||||
(format-spec-make
|
||||
?t (tramp-get-connection-property
|
||||
(tramp-get-connection-process v) "temp-file" "")))
|
||||
spec (list
|
||||
;; "%h" and "%u" do not happen in `tramp-copy-args'
|
||||
;; of `scp', so it is save to use `v'.
|
||||
?h (or (tramp-file-name-host v) "")
|
||||
?u (or (tramp-file-name-user v)
|
||||
;; There might be an interactive setting.
|
||||
(tramp-get-connection-property v "login-as" nil)
|
||||
"")
|
||||
;; For direct remote copying, the port must be the
|
||||
;; same for source and target.
|
||||
?p (or (tramp-file-name-port v) "")
|
||||
?r listener ?c options ?k (if keep-date " " "")
|
||||
?n (concat "2>" (tramp-get-remote-null-device v))
|
||||
?x (tramp-scp-strict-file-name-checking v)
|
||||
?y (tramp-scp-direct-remote-copying v1 v2))
|
||||
copy-program (tramp-get-method-parameter v 'tramp-copy-program)
|
||||
copy-keep-date (tramp-get-method-parameter
|
||||
v 'tramp-copy-keep-date)
|
||||
copy-args
|
||||
;; " " has either been a replacement of "%k" (when
|
||||
;; 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 (tramp-compat-string-search " " 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)
|
||||
remote-copy-args
|
||||
(apply #'tramp-expand-args v 'tramp-remote-copy-args spec))
|
||||
|
||||
;; Set the mode.
|
||||
(unless (and keep-date copy-keep-date)
|
||||
(ignore-errors
|
||||
(set-file-modes newname (tramp-default-file-modes filename)))))
|
||||
;; Check for local copy program.
|
||||
(unless (executable-find copy-program)
|
||||
(tramp-error
|
||||
v 'file-error "Cannot find local copy program: %s" copy-program))
|
||||
|
||||
;; If the operation was `rename', delete the original file.
|
||||
(unless (eq op 'copy)
|
||||
(if (file-regular-p filename)
|
||||
(delete-file filename)
|
||||
(delete-directory filename 'recursive))))))
|
||||
;; Install listener on the remote side. The prompt must be
|
||||
;; consumed later on, when the process does not listen anymore.
|
||||
(when remote-copy-program
|
||||
(unless (with-tramp-connection-property
|
||||
v (concat "remote-copy-program-" remote-copy-program)
|
||||
(tramp-find-executable
|
||||
v remote-copy-program (tramp-get-remote-path v)))
|
||||
(tramp-error
|
||||
v 'file-error
|
||||
"Cannot find remote listener: %s" remote-copy-program))
|
||||
(setq remote-copy-program
|
||||
(mapconcat
|
||||
#'identity
|
||||
(append
|
||||
(list remote-copy-program) remote-copy-args
|
||||
(list (if v1 (concat "<" source) (concat ">" target)) "&"))
|
||||
" "))
|
||||
(tramp-send-command v remote-copy-program)
|
||||
(with-timeout
|
||||
(60 (tramp-error
|
||||
v 'file-error
|
||||
"Listener process not running on remote host: `%s'"
|
||||
remote-copy-program))
|
||||
(tramp-send-command v (format "netstat -l | grep -q :%s" listener))
|
||||
(while (not (tramp-send-command-and-check v nil))
|
||||
(tramp-send-command
|
||||
v (format "netstat -l | grep -q :%s" listener)))))
|
||||
|
||||
(with-temp-buffer
|
||||
(unwind-protect
|
||||
;; The default directory must be remote.
|
||||
(let ((default-directory
|
||||
(file-name-directory (if v1 filename newname)))
|
||||
(process-environment (copy-sequence process-environment)))
|
||||
;; Set the transfer process properties.
|
||||
(tramp-set-connection-property
|
||||
v "process-name" (buffer-name (current-buffer)))
|
||||
(tramp-set-connection-property
|
||||
v "process-buffer" (current-buffer))
|
||||
(when copy-env
|
||||
(tramp-message
|
||||
v 6 "%s=\"%s\""
|
||||
(car copy-env) (string-join (cdr copy-env) " "))
|
||||
(setenv (car copy-env) (string-join (cdr copy-env) " ")))
|
||||
(setq
|
||||
copy-args
|
||||
(append
|
||||
copy-args
|
||||
(if remote-copy-program
|
||||
(list (if v1 (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.
|
||||
p (let ((default-directory
|
||||
tramp-compat-temporary-file-directory))
|
||||
(apply
|
||||
#'start-process
|
||||
(tramp-get-connection-name v)
|
||||
(tramp-get-connection-buffer v)
|
||||
copy-program copy-args)))
|
||||
(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)
|
||||
|
||||
;; We must adapt `tramp-local-end-of-line' for sending
|
||||
;; the password. Also, we indicate that perhaps several
|
||||
;; password prompts might appear.
|
||||
(let ((tramp-local-end-of-line tramp-rsh-end-of-line)
|
||||
(tramp-password-prompt-not-unique (and v1 v2)))
|
||||
(tramp-process-actions
|
||||
p v nil tramp-actions-copy-out-of-band)))
|
||||
|
||||
;; Reset the transfer process properties.
|
||||
(tramp-flush-connection-property v "process-name")
|
||||
(tramp-flush-connection-property v "process-buffer")
|
||||
;; Clear the remote prompt.
|
||||
(when (and remote-copy-program
|
||||
(not (tramp-send-command-and-check v nil)))
|
||||
;; Houston, we have a problem! Likely, the listener is
|
||||
;; still running, so let's clear everything (but the
|
||||
;; cached password).
|
||||
(tramp-cleanup-connection v 'keep-debug 'keep-password))))
|
||||
|
||||
;; Handle KEEP-DATE argument.
|
||||
(when (and keep-date (not copy-keep-date))
|
||||
(tramp-compat-set-file-times
|
||||
newname
|
||||
(file-attribute-modification-time (file-attributes filename))
|
||||
(unless ok-if-already-exists 'nofollow)))
|
||||
|
||||
;; Set the mode.
|
||||
(unless (and keep-date copy-keep-date)
|
||||
(ignore-errors
|
||||
(set-file-modes newname (tramp-default-file-modes filename)))))
|
||||
|
||||
;; If the operation was `rename', delete the original file.
|
||||
(unless (eq op 'copy)
|
||||
(if (file-regular-p filename)
|
||||
(delete-file filename)
|
||||
(delete-directory filename 'recursive)))))
|
||||
|
||||
(defun tramp-sh-handle-make-directory (dir &optional parents)
|
||||
"Like `make-directory' for Tramp files."
|
||||
|
@ -4806,7 +4823,7 @@ Goes through the list `tramp-inline-compress-commands'."
|
|||
((stringp tramp-scp-strict-file-name-checking)
|
||||
tramp-scp-strict-file-name-checking)
|
||||
|
||||
;; Determine the options.
|
||||
;; Determine the option.
|
||||
(t (setq tramp-scp-strict-file-name-checking "")
|
||||
(let ((case-fold-search t))
|
||||
(ignore-errors
|
||||
|
@ -4822,6 +4839,78 @@ Goes through the list `tramp-inline-compress-commands'."
|
|||
(setq tramp-scp-strict-file-name-checking "-T")))))))
|
||||
tramp-scp-strict-file-name-checking)))
|
||||
|
||||
(defun tramp-scp-direct-remote-copying (vec1 vec2)
|
||||
"Return the direct remote copying argument of the local scp."
|
||||
(cond
|
||||
((or (not tramp-use-scp-direct-remote-copying) (null vec1) (null vec2)
|
||||
(not (tramp-get-process vec1))
|
||||
(not (equal (tramp-file-name-port vec1) (tramp-file-name-port vec2)))
|
||||
(null (assoc "%y" (tramp-get-method-parameter vec1 'tramp-copy-args)))
|
||||
(null (assoc "%y" (tramp-get-method-parameter vec2 'tramp-copy-args))))
|
||||
"")
|
||||
|
||||
((let ((case-fold-search t))
|
||||
(and
|
||||
;; Check, whether "scp" supports "-R" option.
|
||||
(with-tramp-connection-property nil "scp-R"
|
||||
(when (executable-find "scp")
|
||||
(with-temp-buffer
|
||||
(tramp-call-process vec1 "scp" nil t nil "-R")
|
||||
(goto-char (point-min))
|
||||
(not (search-forward-regexp
|
||||
"\\(illegal\\|unknown\\) option -- R" nil 'noerror)))))
|
||||
|
||||
;; Check, that RemoteCommand is not used.
|
||||
(with-tramp-connection-property (tramp-get-process vec1) "remote-command"
|
||||
(let ((command `("ssh" "-G" ,(tramp-file-name-host vec1))))
|
||||
(with-temp-buffer
|
||||
(tramp-call-process
|
||||
vec1 tramp-encoding-shell nil t nil
|
||||
tramp-encoding-command-switch
|
||||
(mapconcat #'identity command " "))
|
||||
(goto-char (point-min))
|
||||
(not (search-forward "remotecommand" nil 'noerror)))))
|
||||
|
||||
;; Check hostkeys.
|
||||
(with-tramp-connection-property
|
||||
(tramp-get-process vec1)
|
||||
(concat "direct-remote-copying-"
|
||||
(tramp-make-tramp-file-name vec2 'noloc))
|
||||
(let ((command
|
||||
(append
|
||||
`("ssh" "-G" ,(tramp-file-name-host vec2) "|"
|
||||
"grep" "-i" "^hostname" "|" "cut" "-d\" \"" "-f2" "|"
|
||||
"ssh-keyscan" "-f" "-")
|
||||
(when (tramp-file-name-port vec2)
|
||||
`("-p" ,(tramp-file-name-port vec2)))))
|
||||
found string)
|
||||
(with-temp-buffer
|
||||
;; Check hostkey of VEC2, seen from VEC1.
|
||||
(tramp-send-command vec1 (mapconcat #'identity command " "))
|
||||
;; Check hostkey of VEC2, seen locally.
|
||||
(tramp-call-process
|
||||
vec1 tramp-encoding-shell nil t nil tramp-encoding-command-switch
|
||||
(mapconcat #'identity command " "))
|
||||
(goto-char (point-min))
|
||||
(while (and (not found) (not (eobp)))
|
||||
(setq string
|
||||
(buffer-substring
|
||||
(line-beginning-position) (line-end-position))
|
||||
string
|
||||
(and
|
||||
(string-match "^[^# ]+ \\S-+ \\(\\S-+\\)$" string)
|
||||
(match-string 1 string))
|
||||
found
|
||||
(and string
|
||||
(with-current-buffer (tramp-get-buffer vec1)
|
||||
(goto-char (point-min))
|
||||
(search-forward string nil 'noerror))))
|
||||
(forward-line))
|
||||
found)))))
|
||||
"-R")
|
||||
|
||||
(t "-3")))
|
||||
|
||||
(defun tramp-timeout-session (vec)
|
||||
"Close the connection VEC after a session timeout.
|
||||
If there is just some editing, retry it after 5 seconds."
|
||||
|
@ -5975,9 +6064,6 @@ function cell is returned to be applied on a buffer."
|
|||
;;
|
||||
;; * Use lsh instead of ssh. (Alfred M. Szmidt)
|
||||
;;
|
||||
;; * Optimize out-of-band copying when both methods are scp-like (not
|
||||
;; rsync).
|
||||
;;
|
||||
;; * Keep a second connection open for out-of-band methods like scp or
|
||||
;; rsync.
|
||||
;;
|
||||
|
|
|
@ -255,6 +255,8 @@ pair of the form (KEY VALUE). The following KEYs are defined:
|
|||
- \"%n\" expands to \"2>/dev/null\".
|
||||
- \"%x\" is replaced by the `tramp-scp-strict-file-name-checking'
|
||||
argument if it is supported.
|
||||
- \"%y\" is replaced by the `tramp-scp-direct-remote-copying'
|
||||
argument if it is supported.
|
||||
|
||||
The existence of `tramp-login-args', combined with the
|
||||
absence of `tramp-copy-args', is an indication that the
|
||||
|
@ -1387,6 +1389,11 @@ Will be called once the password has been verified by successful
|
|||
authentication.")
|
||||
(put 'tramp-password-save-function 'tramp-suppress-trace t)
|
||||
|
||||
(defvar tramp-password-prompt-not-unique nil
|
||||
"Whether several passwords might be requested.
|
||||
This shouldn't be set explicitly. It is let-bound, for example
|
||||
during direct remote copying with scp.")
|
||||
|
||||
(defconst tramp-completion-file-name-handler-alist
|
||||
'((file-name-all-completions
|
||||
. tramp-completion-handle-file-name-all-completions)
|
||||
|
@ -4751,7 +4758,9 @@ of."
|
|||
;; Let's check whether a wrong password has been sent already.
|
||||
;; Sometimes, the process returns a new password request
|
||||
;; immediately after rejecting the previous (wrong) one.
|
||||
(unless (tramp-get-connection-property vec "first-password-request" nil)
|
||||
(unless (or tramp-password-prompt-not-unique
|
||||
(tramp-get-connection-property
|
||||
vec "first-password-request" nil))
|
||||
(tramp-clear-passwd vec))
|
||||
(goto-char (point-min))
|
||||
(tramp-check-for-regexp proc tramp-process-action-regexp)
|
||||
|
@ -4759,7 +4768,13 @@ of."
|
|||
;; We don't call `tramp-send-string' in order to hide the
|
||||
;; password from the debug buffer and the traces.
|
||||
(process-send-string
|
||||
proc (concat (tramp-read-passwd proc) tramp-local-end-of-line))
|
||||
proc
|
||||
(concat
|
||||
(funcall
|
||||
(if tramp-password-prompt-not-unique
|
||||
#'tramp-read-passwd-without-cache #'tramp-read-passwd)
|
||||
proc)
|
||||
tramp-local-end-of-line))
|
||||
;; Hide password prompt.
|
||||
(narrow-to-region (point-max) (point-max))))
|
||||
t)
|
||||
|
@ -5705,8 +5720,7 @@ verbosity of 6."
|
|||
;; tramp-cache-read-persistent-data t)'" instead.
|
||||
(defun tramp-read-passwd (proc &optional prompt)
|
||||
"Read a password from user (compat function).
|
||||
Consults the auth-source package.
|
||||
Invokes `password-read' if available, `read-passwd' else."
|
||||
Consults the auth-source package."
|
||||
(let* (;; If `auth-sources' contains "~/.authinfo.gpg", and
|
||||
;; `exec-path' contains a relative file name like ".", it
|
||||
;; could happen that the "gpg" command is not found. So we
|
||||
|
@ -5783,6 +5797,21 @@ Invokes `password-read' if available, `read-passwd' else."
|
|||
|
||||
(put #'tramp-read-passwd 'tramp-suppress-trace t)
|
||||
|
||||
(defun tramp-read-passwd-without-cache (proc &optional prompt)
|
||||
"Read a password from user (compat function)."
|
||||
;; We suspend the timers while reading the password.
|
||||
(let ((stimers (with-timeout-suspend)))
|
||||
(unwind-protect
|
||||
(password-read
|
||||
(or prompt
|
||||
(with-current-buffer (process-buffer proc)
|
||||
(tramp-check-for-regexp proc tramp-password-prompt-regexp)
|
||||
(match-string 0))))
|
||||
;; Reenable the timers.
|
||||
(with-timeout-unsuspend stimers))))
|
||||
|
||||
(put #'tramp-read-passwd-without-cache 'tramp-suppress-trace t)
|
||||
|
||||
(defun tramp-clear-passwd (vec)
|
||||
"Clear password cache for connection related to VEC."
|
||||
(let ((method (tramp-file-name-method vec))
|
||||
|
|
Loading…
Add table
Reference in a new issue