Provide public SCP command line builder (Fixes \#951)

Signed-off-by: Jeroen van Erp <jeroen@hierynomus.com>
This commit is contained in:
Jeroen van Erp
2024-08-20 14:46:50 +02:00
parent 54376b7622
commit 93046f315e
2 changed files with 33 additions and 21 deletions

View File

@@ -20,6 +20,7 @@ import net.schmizz.sshj.common.StreamCopier;
import net.schmizz.sshj.xfer.LocalFileFilter;
import net.schmizz.sshj.xfer.LocalSourceFile;
import net.schmizz.sshj.xfer.TransferListener;
import net.schmizz.sshj.xfer.scp.ScpCommandLine.Arg;
import java.io.IOException;
import java.io.InputStream;
@@ -43,37 +44,44 @@ public class SCPUploadClient extends AbstractSCPClient {
return copy(sourceFile, remotePath, ScpCommandLine.EscapeMode.SingleQuote);
}
public synchronized int copy (LocalSourceFile sourceFile, String remotePath, ScpCommandLine.EscapeMode escapeMode) throws IOException {
public synchronized int copy(LocalSourceFile sourceFile, String remotePath, ScpCommandLine.EscapeMode escapeMode)
throws IOException {
return copy(sourceFile, remotePath, escapeMode, true);
}
public synchronized int copy(LocalSourceFile sourceFile, String remotePath, ScpCommandLine.EscapeMode escapeMode, boolean preserveTimes)
throws IOException {
throws IOException {
ScpCommandLine commandLine = ScpCommandLine.with(ScpCommandLine.Arg.SINK)
.and(ScpCommandLine.Arg.RECURSIVE)
.and(ScpCommandLine.Arg.LIMIT, String.valueOf(bandwidthLimit), (bandwidthLimit > 0));
if (preserveTimes) {
commandLine.and(ScpCommandLine.Arg.PRESERVE_TIMES, sourceFile.providesAtimeMtime());
}
return copy(sourceFile, remotePath, escapeMode, commandLine);
}
public synchronized int copy(LocalSourceFile sourceFile, String remotePath, ScpCommandLine.EscapeMode escapeMode, ScpCommandLine commandLine)
throws IOException {
engine.cleanSlate();
try {
startCopy(sourceFile, remotePath, escapeMode, preserveTimes);
commandLine.withPath(remotePath, escapeMode);
startCopy(sourceFile, commandLine);
} finally {
engine.exit();
}
return engine.getExitStatus();
}
public void setUploadFilter(LocalFileFilter uploadFilter) {
this.uploadFilter = uploadFilter;
}
private void startCopy(LocalSourceFile sourceFile, String targetPath, ScpCommandLine.EscapeMode escapeMode, boolean preserveTimes)
private void startCopy(LocalSourceFile sourceFile, ScpCommandLine commandLine)
throws IOException {
ScpCommandLine commandLine = ScpCommandLine.with(ScpCommandLine.Arg.SINK)
.and(ScpCommandLine.Arg.RECURSIVE)
.and(ScpCommandLine.Arg.LIMIT, String.valueOf(bandwidthLimit), (bandwidthLimit > 0));
if (preserveTimes) {
commandLine.and(ScpCommandLine.Arg.PRESERVE_TIMES, sourceFile.providesAtimeMtime());
}
commandLine.withPath(targetPath, escapeMode);
engine.execSCPWith(commandLine);
engine.check("Start status OK");
process(engine.getTransferListener(), sourceFile, preserveTimes);
process(engine.getTransferListener(), sourceFile, commandLine.has(Arg.PRESERVE_TIMES));
}
private void process(TransferListener listener, LocalSourceFile f, boolean preserveTimes)

View File

@@ -24,7 +24,7 @@ public class ScpCommandLine {
private static final String SCP_COMMAND = "scp";
private EscapeMode mode;
enum Arg {
public enum Arg {
SOURCE('f'),
SINK('t'),
RECURSIVE('r'),
@@ -77,19 +77,19 @@ public class ScpCommandLine {
ScpCommandLine() {
}
static ScpCommandLine with(Arg name) {
public static ScpCommandLine with(Arg name) {
return with(name, null, true);
}
static ScpCommandLine with(Arg name, String value) {
public static ScpCommandLine with(Arg name, String value) {
return with(name, value, true);
}
static ScpCommandLine with(Arg name, boolean accept) {
public static ScpCommandLine with(Arg name, boolean accept) {
return with(name, null, accept);
}
static ScpCommandLine with(Arg name, String value, boolean accept) {
public static ScpCommandLine with(Arg name, String value, boolean accept) {
ScpCommandLine commandLine = new ScpCommandLine();
commandLine.addArgument(name, value, accept);
return commandLine;
@@ -101,22 +101,22 @@ public class ScpCommandLine {
}
}
ScpCommandLine and(Arg name) {
public ScpCommandLine and(Arg name) {
addArgument(name, null, true);
return this;
}
ScpCommandLine and(Arg name, String value) {
public ScpCommandLine and(Arg name, String value) {
addArgument(name, value, true);
return this;
}
ScpCommandLine and(Arg name, boolean accept) {
public ScpCommandLine and(Arg name, boolean accept) {
addArgument(name, null, accept);
return this;
}
ScpCommandLine and(Arg name, String value, boolean accept) {
public ScpCommandLine and(Arg name, String value, boolean accept) {
addArgument(name, value, accept);
return this;
}
@@ -127,6 +127,10 @@ public class ScpCommandLine {
return this;
}
boolean has(Arg arg) {
return arguments.containsKey(arg);
}
String toCommandLine() {
final StringBuilder cmd = new StringBuilder(SCP_COMMAND);
for (Arg arg : arguments.keySet()) {