mirror of
https://github.com/hierynomus/sshj.git
synced 2025-12-06 07:10:53 +03:00
Remove inheritance coupling between SCP*Clients
Use delegation to SCPEngine instead of inheritance. Remove methods using String path for source file.
This commit is contained in:
committed by
Shikhar Bhushan
parent
41ac277023
commit
aa9f4e192f
@@ -15,37 +15,44 @@
|
||||
*/
|
||||
package net.schmizz.sshj.xfer.scp;
|
||||
|
||||
import net.schmizz.sshj.common.IOUtils;
|
||||
import net.schmizz.sshj.common.SSHException;
|
||||
import net.schmizz.sshj.connection.channel.direct.SessionFactory;
|
||||
import net.schmizz.sshj.xfer.FileTransferUtil;
|
||||
import net.schmizz.sshj.xfer.ModeSetter;
|
||||
import net.schmizz.sshj.xfer.TransferListener;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import net.schmizz.sshj.common.IOUtils;
|
||||
import net.schmizz.sshj.common.SSHException;
|
||||
import net.schmizz.sshj.connection.channel.direct.SessionFactory;
|
||||
import net.schmizz.sshj.xfer.FileTransferUtil;
|
||||
import net.schmizz.sshj.xfer.ModeSetter;
|
||||
import net.schmizz.sshj.xfer.TransferListener;
|
||||
import net.schmizz.sshj.xfer.scp.SCPEngine.Arg;
|
||||
|
||||
/** Support for uploading files over a connected link using SCP. */
|
||||
public final class SCPDownloadClient
|
||||
extends SCPEngine {
|
||||
public final class SCPDownloadClient {
|
||||
|
||||
private final ModeSetter modeSetter;
|
||||
|
||||
private boolean recursive = true;
|
||||
|
||||
private SCPEngine engine;
|
||||
|
||||
SCPDownloadClient(SessionFactory host, TransferListener listener, ModeSetter modeSetter) {
|
||||
super(host, listener);
|
||||
engine = new SCPEngine(host, listener);
|
||||
this.modeSetter = modeSetter;
|
||||
}
|
||||
|
||||
/** Download a file from {@code sourcePath} on the connected host to {@code targetPath} locally. */
|
||||
@Override
|
||||
public synchronized int copy(String sourcePath, String targetPath)
|
||||
throws IOException {
|
||||
return super.copy(sourcePath, targetPath);
|
||||
engine.cleanSlate();
|
||||
try {
|
||||
startCopy(sourcePath, targetPath);
|
||||
} finally {
|
||||
engine.exit();
|
||||
}
|
||||
return engine.exitStatus;
|
||||
}
|
||||
|
||||
public boolean getRecursive() {
|
||||
@@ -56,17 +63,16 @@ public final class SCPDownloadClient
|
||||
this.recursive = recursive;
|
||||
}
|
||||
|
||||
@Override
|
||||
void startCopy(String sourcePath, String targetPath)
|
||||
throws IOException {
|
||||
init(sourcePath);
|
||||
|
||||
signal("Start status OK");
|
||||
engine.signal("Start status OK");
|
||||
|
||||
String msg = readMessage(true);
|
||||
String msg = engine.readMessage(true);
|
||||
do
|
||||
process(null, msg, new File(targetPath));
|
||||
while ((msg = readMessage(false)) != null);
|
||||
while ((msg = engine.readMessage(false)) != null);
|
||||
}
|
||||
|
||||
private void init(String source)
|
||||
@@ -78,7 +84,7 @@ public final class SCPDownloadClient
|
||||
args.add(Arg.RECURSIVE);
|
||||
if (modeSetter.preservesTimes())
|
||||
args.add(Arg.PRESERVE_TIMES);
|
||||
execSCPWith(args, source);
|
||||
engine.execSCPWith(args, source);
|
||||
}
|
||||
|
||||
private long parseLong(String longString, String valType)
|
||||
@@ -107,8 +113,8 @@ public final class SCPDownloadClient
|
||||
switch (msg.charAt(0)) {
|
||||
|
||||
case 'T':
|
||||
signal("ACK: T");
|
||||
process(msg, readMessage(true), f);
|
||||
engine.signal("ACK: T");
|
||||
process(msg, engine.readMessage(true), f);
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
@@ -128,7 +134,7 @@ public final class SCPDownloadClient
|
||||
|
||||
default:
|
||||
String err = "Unrecognized message: `" + msg + "`";
|
||||
sendMessage((char) 2 + err);
|
||||
engine.sendMessage((char) 2 + err);
|
||||
throw new SCPException(err);
|
||||
}
|
||||
|
||||
@@ -142,16 +148,16 @@ public final class SCPDownloadClient
|
||||
final String dirname = dMsgParts[2];
|
||||
if (length != 0)
|
||||
throw new IOException("Remote SCP command sent strange directory length: " + length);
|
||||
listener.startedDir(dirname);
|
||||
engine.listener.startedDir(dirname);
|
||||
{
|
||||
f = FileTransferUtil.getTargetDirectory(f, dirname);
|
||||
signal("ACK: D");
|
||||
engine.signal("ACK: D");
|
||||
do {
|
||||
} while (!process(null, readMessage(), f));
|
||||
} while (!process(null, engine.readMessage(), f));
|
||||
setAttributes(f, parsePermissions(dMsgParts[0]), tMsg);
|
||||
signal("ACK: E");
|
||||
engine.signal("ACK: E");
|
||||
}
|
||||
listener.finishedDir();
|
||||
engine.listener.finishedDir();
|
||||
}
|
||||
|
||||
private void processFile(String cMsg, String tMsg, File f)
|
||||
@@ -159,21 +165,21 @@ public final class SCPDownloadClient
|
||||
final String[] cMsgParts = tokenize(cMsg, 3); // C<perms> <size> <filename>
|
||||
final long length = parseLong(cMsgParts[1], "length");
|
||||
final String filename = cMsgParts[2];
|
||||
listener.startedFile(filename, length);
|
||||
engine.listener.startedFile(filename, length);
|
||||
{
|
||||
f = FileTransferUtil.getTargetFile(f, filename);
|
||||
signal("Remote can start transfer");
|
||||
engine.signal("Remote can start transfer");
|
||||
final FileOutputStream fos = new FileOutputStream(f);
|
||||
try {
|
||||
transfer(scp.getInputStream(), fos, scp.getLocalMaxPacketSize(), length);
|
||||
engine.transfer(engine.scp.getInputStream(), fos, engine.scp.getLocalMaxPacketSize(), length);
|
||||
} finally {
|
||||
IOUtils.closeQuietly(fos);
|
||||
}
|
||||
check("Remote agrees transfer done");
|
||||
engine.check("Remote agrees transfer done");
|
||||
setAttributes(f, parsePermissions(cMsgParts[0]), tMsg);
|
||||
signal("Transfer done");
|
||||
engine.signal("Transfer done");
|
||||
}
|
||||
listener.finishedFile();
|
||||
engine.listener.finishedFile();
|
||||
}
|
||||
|
||||
private void setAttributes(File f, int perms, String tMsg)
|
||||
|
||||
@@ -15,23 +15,22 @@
|
||||
*/
|
||||
package net.schmizz.sshj.xfer.scp;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.List;
|
||||
|
||||
import net.schmizz.sshj.common.IOUtils;
|
||||
import net.schmizz.sshj.common.SSHException;
|
||||
import net.schmizz.sshj.connection.channel.direct.Session.Command;
|
||||
import net.schmizz.sshj.connection.channel.direct.SessionFactory;
|
||||
import net.schmizz.sshj.xfer.TransferListener;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
|
||||
/** @see <a href="http://blogs.sun.com/janp/entry/how_the_scp_protocol_works">SCP Protocol</a> */
|
||||
abstract class SCPEngine {
|
||||
class SCPEngine {
|
||||
|
||||
static enum Arg {
|
||||
SOURCE('f'),
|
||||
@@ -70,17 +69,6 @@ abstract class SCPEngine {
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
public int copy(String sourcePath, String targetPath)
|
||||
throws IOException {
|
||||
cleanSlate();
|
||||
try {
|
||||
startCopy(sourcePath, targetPath);
|
||||
} finally {
|
||||
exit();
|
||||
}
|
||||
return exitStatus;
|
||||
}
|
||||
|
||||
public int getExitStatus() {
|
||||
return exitStatus;
|
||||
}
|
||||
@@ -173,9 +161,6 @@ abstract class SCPEngine {
|
||||
scp.getOutputStream().flush();
|
||||
}
|
||||
|
||||
abstract void startCopy(String sourcePath, String targetPath)
|
||||
throws IOException;
|
||||
|
||||
void transfer(InputStream in, OutputStream out, int bufSize, long len)
|
||||
throws IOException {
|
||||
final byte[] buf = new byte[bufSize];
|
||||
|
||||
@@ -19,6 +19,7 @@ import java.io.IOException;
|
||||
|
||||
import net.schmizz.sshj.connection.channel.direct.SessionFactory;
|
||||
import net.schmizz.sshj.xfer.AbstractFileTransfer;
|
||||
import net.schmizz.sshj.xfer.FileSystemFile;
|
||||
import net.schmizz.sshj.xfer.FileTransfer;
|
||||
import net.schmizz.sshj.xfer.LocalFile;
|
||||
|
||||
@@ -49,7 +50,7 @@ public class SCPFileTransfer
|
||||
@Override
|
||||
public void upload(String localPath, String remotePath)
|
||||
throws IOException {
|
||||
newSCPUploadClient().copy(localPath, remotePath);
|
||||
newSCPUploadClient().copy(new FileSystemFile(localPath), remotePath);
|
||||
}
|
||||
|
||||
public void upload(LocalFile localFile, String remotePath)
|
||||
|
||||
@@ -29,55 +29,42 @@ import net.schmizz.sshj.connection.channel.direct.SessionFactory;
|
||||
import net.schmizz.sshj.xfer.LocalFile;
|
||||
import net.schmizz.sshj.xfer.ModeGetter;
|
||||
import net.schmizz.sshj.xfer.TransferListener;
|
||||
import net.schmizz.sshj.xfer.scp.SCPEngine.Arg;
|
||||
|
||||
/** Support for uploading files over a connected link using SCP. */
|
||||
public final class SCPUploadClient
|
||||
extends SCPEngine {
|
||||
public final class SCPUploadClient {
|
||||
|
||||
private final ModeGetter modeGetter;
|
||||
|
||||
private FileFilter fileFilter;
|
||||
|
||||
SCPUploadClient(SessionFactory host, TransferListener listener, ModeGetter modeGetter) {
|
||||
super(host, listener);
|
||||
this.modeGetter = modeGetter;
|
||||
}
|
||||
private SCPEngine engine;
|
||||
|
||||
/** Upload a file from {@code sourcePath} locally to {@code targetPath} on the remote host. */
|
||||
@Override
|
||||
public synchronized int copy(String sourcePath, String targetPath)
|
||||
throws IOException {
|
||||
return super.copy(sourcePath, targetPath);
|
||||
SCPUploadClient(SessionFactory host, TransferListener listener, ModeGetter modeGetter) {
|
||||
engine = new SCPEngine(host, listener);
|
||||
this.modeGetter = modeGetter;
|
||||
}
|
||||
|
||||
/** Upload a local file from {@code localFile} to {@code targetPath} on the remote host. */
|
||||
public synchronized int copy(LocalFile sourceFile, String remotePath)
|
||||
throws IOException {
|
||||
cleanSlate();
|
||||
engine.cleanSlate();
|
||||
try {
|
||||
startCopy(sourceFile, remotePath);
|
||||
} finally {
|
||||
exit();
|
||||
engine.exit();
|
||||
}
|
||||
return exitStatus;
|
||||
return engine.exitStatus;
|
||||
}
|
||||
|
||||
public void setFileFilter(FileFilter fileFilter) {
|
||||
this.fileFilter = fileFilter;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected synchronized void startCopy(String sourcePath, String targetPath)
|
||||
throws IOException {
|
||||
init(targetPath);
|
||||
check("Start status OK");
|
||||
process(new File(sourcePath));
|
||||
}
|
||||
|
||||
protected synchronized void startCopy(LocalFile sourceFile, String targetPath)
|
||||
private synchronized void startCopy(LocalFile sourceFile, String targetPath)
|
||||
throws IOException {
|
||||
init(targetPath);
|
||||
check("Start status OK");
|
||||
engine.check("Start status OK");
|
||||
process(sourceFile);
|
||||
}
|
||||
|
||||
@@ -96,19 +83,19 @@ public final class SCPUploadClient
|
||||
args.add(Arg.RECURSIVE);
|
||||
if (modeGetter.preservesTimes())
|
||||
args.add(Arg.PRESERVE_TIMES);
|
||||
execSCPWith(args, target);
|
||||
engine.execSCPWith(args, target);
|
||||
}
|
||||
|
||||
private void process(File f)
|
||||
throws IOException {
|
||||
if (f.isDirectory()) {
|
||||
listener.startedDir(f.getName());
|
||||
engine.listener.startedDir(f.getName());
|
||||
sendDirectory(f);
|
||||
listener.finishedDir();
|
||||
engine.listener.finishedDir();
|
||||
} else if (f.isFile()) {
|
||||
listener.startedFile(f.getName(), f.length());
|
||||
engine.listener.startedFile(f.getName(), f.length());
|
||||
sendFile(f);
|
||||
listener.finishedFile();
|
||||
engine.listener.finishedFile();
|
||||
} else
|
||||
throw new IOException(f + " is not a regular file or directory");
|
||||
}
|
||||
@@ -116,13 +103,13 @@ public final class SCPUploadClient
|
||||
private void process(LocalFile f)
|
||||
throws IOException {
|
||||
if (f.isDirectory()) {
|
||||
listener.startedDir(f.getName());
|
||||
engine.listener.startedDir(f.getName());
|
||||
sendDirectory(f);
|
||||
listener.finishedDir();
|
||||
engine.listener.finishedDir();
|
||||
} else if (f.isFile()) {
|
||||
listener.startedFile(f.getName(), f.length());
|
||||
engine.listener.startedFile(f.getName(), f.length());
|
||||
sendFile(f);
|
||||
listener.finishedFile();
|
||||
engine.listener.finishedFile();
|
||||
} else
|
||||
throw new IOException(f + " is not a regular file or directory");
|
||||
}
|
||||
@@ -130,19 +117,19 @@ public final class SCPUploadClient
|
||||
private void sendDirectory(File f)
|
||||
throws IOException {
|
||||
preserveTimeIfPossible(f);
|
||||
sendMessage("D0" + getPermString(f) + " 0 " + f.getName());
|
||||
engine.sendMessage("D0" + getPermString(f) + " 0 " + f.getName());
|
||||
for (File child : getChildren(f))
|
||||
process(child);
|
||||
sendMessage("E");
|
||||
engine.sendMessage("E");
|
||||
}
|
||||
|
||||
private void sendDirectory(LocalFile f)
|
||||
throws IOException {
|
||||
preserveTimeIfPossible(f);
|
||||
sendMessage("D0" + getPermString(f) + " 0 " + f.getName());
|
||||
engine.sendMessage("D0" + getPermString(f) + " 0 " + f.getName());
|
||||
for (LocalFile child : f.getChildren())
|
||||
process(child);
|
||||
sendMessage("E");
|
||||
engine.sendMessage("E");
|
||||
}
|
||||
|
||||
private void sendFile(File f)
|
||||
@@ -150,10 +137,10 @@ public final class SCPUploadClient
|
||||
preserveTimeIfPossible(f);
|
||||
final InputStream src = new FileInputStream(f);
|
||||
try {
|
||||
sendMessage("C0" + getPermString(f) + " " + f.length() + " " + f.getName());
|
||||
transfer(src, scp.getOutputStream(), scp.getRemoteMaxPacketSize(), f.length());
|
||||
signal("Transfer done");
|
||||
check("Remote agrees transfer done");
|
||||
engine.sendMessage("C0" + getPermString(f) + " " + f.length() + " " + f.getName());
|
||||
engine.transfer(src, engine.scp.getOutputStream(), engine.scp.getRemoteMaxPacketSize(), f.length());
|
||||
engine.signal("Transfer done");
|
||||
engine.check("Remote agrees transfer done");
|
||||
} finally {
|
||||
IOUtils.closeQuietly(src);
|
||||
}
|
||||
@@ -164,10 +151,10 @@ public final class SCPUploadClient
|
||||
preserveTimeIfPossible(f);
|
||||
final InputStream src = f.stream();
|
||||
try {
|
||||
sendMessage("C0" + getPermString(f) + " " + f.length() + " " + f.getName());
|
||||
transfer(src, scp.getOutputStream(), scp.getRemoteMaxPacketSize(), f.length());
|
||||
signal("Transfer done");
|
||||
check("Remote agrees transfer done");
|
||||
engine.sendMessage("C0" + getPermString(f) + " " + f.length() + " " + f.getName());
|
||||
engine.transfer(src, engine.scp.getOutputStream(), engine.scp.getRemoteMaxPacketSize(), f.length());
|
||||
engine.signal("Transfer done");
|
||||
engine.check("Remote agrees transfer done");
|
||||
} finally {
|
||||
IOUtils.closeQuietly(src);
|
||||
}
|
||||
@@ -176,13 +163,13 @@ public final class SCPUploadClient
|
||||
private void preserveTimeIfPossible(File f)
|
||||
throws IOException {
|
||||
if (modeGetter.preservesTimes())
|
||||
sendMessage("T" + modeGetter.getLastModifiedTime(f) + " 0 " + modeGetter.getLastAccessTime(f) + " 0");
|
||||
engine.sendMessage("T" + modeGetter.getLastModifiedTime(f) + " 0 " + modeGetter.getLastAccessTime(f) + " 0");
|
||||
}
|
||||
|
||||
private void preserveTimeIfPossible(LocalFile f)
|
||||
throws IOException {
|
||||
if (modeGetter.preservesTimes())
|
||||
sendMessage("T" + modeGetter.getLastModifiedTime(f) + " 0 " + modeGetter.getLastAccessTime(f) + " 0");
|
||||
engine.sendMessage("T" + modeGetter.getLastModifiedTime(f) + " 0 " + modeGetter.getLastAccessTime(f) + " 0");
|
||||
}
|
||||
|
||||
private String getPermString(File f)
|
||||
|
||||
Reference in New Issue
Block a user