in sshd-cli/src/main/java/org/apache/sshd/cli/client/ScpCommandMain.java [330:435]
public static void xferRemoteToRemote(
BufferedReader stdin, PrintStream stdout, PrintStream stderr, String[] args,
ScpLocation source, ScpLocation target, Collection<Option> options,
OutputStream logStream, Level level, boolean quiet)
throws Exception {
ClientSession srcSession = ((logStream == null) || GenericUtils.isEmpty(args))
? null : setupClientSession(SCP_PORT_OPTION, stdin, level, stdout, stderr, args);
if (srcSession == null) {
showUsageMessage(stderr);
System.exit(-1);
return; // not that we really need it...
}
try {
ClientFactoryManager manager = srcSession.getFactoryManager();
// TODO see if there is a way to specify a different port or proxy jump for the target
HostConfigEntry entry = resolveHost(
manager, target.resolveUsername(), target.getHost(), target.resolvePort(), null);
// TODO use a configurable wait time
ClientSession dstSession = manager.connect(entry, null, null)
.verify(CliClientModuleProperties.CONECT_TIMEOUT.getRequired(srcSession))
.getSession();
try {
// TODO see if there is a way to specify different password/key for target
// copy non-default identities from source session
AuthenticationIdentitiesProvider provider = srcSession.getRegisteredIdentities();
Iterable<?> ids = (provider == null) ? null : provider.loadIdentities(srcSession);
Iterator<?> iter = (ids == null) ? null : ids.iterator();
while ((iter != null) && iter.hasNext()) {
Object v = iter.next();
if (v instanceof String) {
dstSession.addPasswordIdentity((String) v);
} else if (v instanceof KeyPair) {
dstSession.addPublicKeyIdentity((KeyPair) v);
} else {
throw new UnsupportedOperationException("Unsupported source identity: " + v);
}
}
dstSession.auth().verify(CliClientModuleProperties.AUTH_TIMEOUT.getRequired(dstSession));
ScpRemote2RemoteTransferListener listener = quiet ? null : new ScpRemote2RemoteTransferListener() {
@Override
public void startDirectFileTransfer(
ClientSession srcSession, String source,
ClientSession dstSession, String destination,
ScpTimestampCommandDetails timestamp, ScpReceiveFileCommandDetails details)
throws IOException {
logEvent("FILE-START: ", source, destination, null);
}
@Override
public void startDirectDirectoryTransfer(
ClientSession srcSession, String source,
ClientSession dstSession, String destination,
ScpTimestampCommandDetails timestamp, ScpReceiveDirCommandDetails details)
throws IOException {
logEvent("DIR-START: ", source, destination, null);
}
@Override
public void endDirectFileTransfer(
ClientSession srcSession, String source,
ClientSession dstSession, String destination,
ScpTimestampCommandDetails timestamp, ScpReceiveFileCommandDetails details,
long xferSize, Throwable thrown)
throws IOException {
logEvent("FILE-END: ", source, destination, thrown);
}
@Override
public void endDirectDirectoryTransfer(
ClientSession srcSession, String source,
ClientSession dstSession, String destination,
ScpTimestampCommandDetails timestamp, ScpReceiveDirCommandDetails details,
Throwable thrown)
throws IOException {
logEvent("DIR-END: ", source, destination, thrown);
}
private void logEvent(String event, String src, String dst, Throwable thrown) {
PrintStream ps = (thrown == null) ? stdout : stderr;
ps.append(" ").append(event)
.append(' ').append(src).append(" ==> ").append(dst);
if (thrown != null) {
ps.append(" - ").append(thrown.getClass().getSimpleName()).append(": ")
.append(thrown.getMessage());
}
ps.println();
}
};
ScpRemote2RemoteTransferHelper helper = new ScpRemote2RemoteTransferHelper(srcSession, dstSession, listener);
boolean preserveAttributes = GenericUtils.isNotEmpty(options) && options.contains(Option.PreserveAttributes);
if (GenericUtils.isNotEmpty(options)
&& (options.contains(Option.Recursive) || options.contains(Option.TargetIsDirectory))) {
helper.transferDirectory(source.getPath(), target.getPath(), preserveAttributes);
} else {
helper.transferFile(source.getPath(), target.getPath(), preserveAttributes);
}
} finally {
dstSession.close();
}
} finally {
srcSession.close();
}
}