mirror of
https://github.com/hierynomus/sshj.git
synced 2025-12-06 15:20:54 +03:00
scp/ reformat
This commit is contained in:
@@ -22,7 +22,8 @@ import java.io.IOException;
|
||||
* Default implementation of {@link ModeGetter} that supplies file permissions as {@code "0644"}, directory permissions
|
||||
* as {@code "0755"}, and does not supply mtime and atime.
|
||||
*/
|
||||
public class DefaultModeGetter implements ModeGetter {
|
||||
public class DefaultModeGetter
|
||||
implements ModeGetter {
|
||||
|
||||
public long getLastAccessTime(File f) {
|
||||
return 0;
|
||||
@@ -33,7 +34,8 @@ public class DefaultModeGetter implements ModeGetter {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int getPermissions(File f) throws IOException {
|
||||
public int getPermissions(File f)
|
||||
throws IOException {
|
||||
if (f.isDirectory())
|
||||
return 0755;
|
||||
else if (f.isFile())
|
||||
|
||||
@@ -20,17 +20,21 @@ import java.io.IOException;
|
||||
|
||||
|
||||
/** Default implementation of {@link ModeSetter} that does not set any permissions or preserve mtime and atime. */
|
||||
public class DefaultModeSetter implements ModeSetter {
|
||||
public class DefaultModeSetter
|
||||
implements ModeSetter {
|
||||
|
||||
public void setLastAccessedTime(File f, long t) throws IOException {
|
||||
public void setLastAccessedTime(File f, long t)
|
||||
throws IOException {
|
||||
// can't do ntn
|
||||
}
|
||||
|
||||
public void setLastModifiedTime(File f, long t) throws IOException {
|
||||
public void setLastModifiedTime(File f, long t)
|
||||
throws IOException {
|
||||
// f.setLastModified(t * 1000);
|
||||
}
|
||||
|
||||
public void setPermissions(File f, int perms) throws IOException {
|
||||
public void setPermissions(File f, int perms)
|
||||
throws IOException {
|
||||
// TODO: set user's rwx permissions; can't do anything about group and world
|
||||
}
|
||||
|
||||
|
||||
@@ -19,9 +19,11 @@ import java.io.IOException;
|
||||
|
||||
public interface FileTransfer {
|
||||
|
||||
void upload(String localPath, String remotePath) throws IOException;
|
||||
void upload(String localPath, String remotePath)
|
||||
throws IOException;
|
||||
|
||||
void download(String remotePath, String localPath) throws IOException;
|
||||
void download(String remotePath, String localPath)
|
||||
throws IOException;
|
||||
|
||||
ModeGetter getModeGetter();
|
||||
|
||||
|
||||
@@ -20,7 +20,8 @@ import java.io.IOException;
|
||||
|
||||
public class FileTransferUtil {
|
||||
|
||||
public static File getTargetDirectory(File f, String dirname) throws IOException {
|
||||
public static File getTargetDirectory(File f, String dirname)
|
||||
throws IOException {
|
||||
if (f.exists())
|
||||
if (f.isDirectory()) {
|
||||
if (!f.getName().equals(dirname))
|
||||
@@ -34,7 +35,8 @@ public class FileTransferUtil {
|
||||
return f;
|
||||
}
|
||||
|
||||
public static File getTargetFile(File f, String filename) throws IOException {
|
||||
public static File getTargetFile(File f, String filename)
|
||||
throws IOException {
|
||||
if (f.isDirectory())
|
||||
f = new File(f, filename);
|
||||
|
||||
|
||||
@@ -30,7 +30,8 @@ public interface ModeGetter {
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
long getLastAccessTime(File f) throws IOException;
|
||||
long getLastAccessTime(File f)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* Returns last modified time for {@code f}.
|
||||
@@ -41,7 +42,8 @@ public interface ModeGetter {
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
long getLastModifiedTime(File f) throws IOException;
|
||||
long getLastModifiedTime(File f)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* Returns the permissions for {@code f}.
|
||||
@@ -52,7 +54,8 @@ public interface ModeGetter {
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
int getPermissions(File f) throws IOException;
|
||||
int getPermissions(File f)
|
||||
throws IOException;
|
||||
|
||||
/** Whether this implementation can provide mtime and atime information. */
|
||||
boolean preservesTimes();
|
||||
|
||||
@@ -29,7 +29,8 @@ public interface ModeSetter {
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
void setLastAccessedTime(File f, long t) throws IOException;
|
||||
void setLastAccessedTime(File f, long t)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* Set the last modified time for {@code f}.
|
||||
@@ -39,7 +40,8 @@ public interface ModeSetter {
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
void setLastModifiedTime(File f, long t) throws IOException;
|
||||
void setLastModifiedTime(File f, long t)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* Set the permissions for {@code f}.
|
||||
@@ -49,7 +51,8 @@ public interface ModeSetter {
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
void setPermissions(File f, int perms) throws IOException;
|
||||
void setPermissions(File f, int perms)
|
||||
throws IOException;
|
||||
|
||||
/** Whether this implementation is interested in preserving mtime and atime. */
|
||||
boolean preservesTimes();
|
||||
|
||||
@@ -28,7 +28,8 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/** Support for uploading files over a connected {@link net.schmizz.sshj.SSHClient} link using SCP. */
|
||||
public final class SCPDownloadClient extends SCPEngine {
|
||||
public final class SCPDownloadClient
|
||||
extends SCPEngine {
|
||||
|
||||
private final ModeSetter modeSetter;
|
||||
|
||||
@@ -41,7 +42,8 @@ public final class SCPDownloadClient extends SCPEngine {
|
||||
|
||||
/** 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 {
|
||||
public synchronized int copy(String sourcePath, String targetPath)
|
||||
throws IOException {
|
||||
return super.copy(sourcePath, targetPath);
|
||||
}
|
||||
|
||||
@@ -54,7 +56,8 @@ public final class SCPDownloadClient extends SCPEngine {
|
||||
}
|
||||
|
||||
@Override
|
||||
void startCopy(String sourcePath, String targetPath) throws IOException {
|
||||
void startCopy(String sourcePath, String targetPath)
|
||||
throws IOException {
|
||||
init(sourcePath);
|
||||
|
||||
signal("Start status OK");
|
||||
@@ -65,7 +68,8 @@ public final class SCPDownloadClient extends SCPEngine {
|
||||
while ((msg = readMessage(false)) != null);
|
||||
}
|
||||
|
||||
private void init(String source) throws SSHException {
|
||||
private void init(String source)
|
||||
throws SSHException {
|
||||
List<Arg> args = new LinkedList<Arg>();
|
||||
args.add(Arg.SOURCE);
|
||||
args.add(Arg.QUIET);
|
||||
@@ -76,7 +80,8 @@ public final class SCPDownloadClient extends SCPEngine {
|
||||
execSCPWith(args, source);
|
||||
}
|
||||
|
||||
private long parseLong(String longString, String valType) throws SCPException {
|
||||
private long parseLong(String longString, String valType)
|
||||
throws SCPException {
|
||||
try {
|
||||
return Long.parseLong(longString);
|
||||
} catch (NumberFormatException nfe) {
|
||||
@@ -86,13 +91,15 @@ public final class SCPDownloadClient extends SCPEngine {
|
||||
|
||||
/* e.g. "C0644" -> 0644; "D0755" -> 0755 */
|
||||
|
||||
private int parsePermissions(String cmd) throws SCPException {
|
||||
private int parsePermissions(String cmd)
|
||||
throws SCPException {
|
||||
if (cmd.length() != 5)
|
||||
throw new SCPException("Could not parse permissions from `" + cmd + "`");
|
||||
return Integer.parseInt(cmd.substring(1), 8);
|
||||
}
|
||||
|
||||
private void prepare(File f, int perms, String tMsg) throws IOException {
|
||||
private void prepare(File f, int perms, String tMsg)
|
||||
throws IOException {
|
||||
modeSetter.setPermissions(f, perms);
|
||||
|
||||
if (tMsg != null && modeSetter.preservesTimes()) {
|
||||
@@ -102,7 +109,8 @@ public final class SCPDownloadClient extends SCPEngine {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean process(String bufferedTMsg, String msg, File f) throws IOException {
|
||||
private boolean process(String bufferedTMsg, String msg, File f)
|
||||
throws IOException {
|
||||
if (msg.length() < 1)
|
||||
throw new SCPException("Could not parse message `" + msg + "`");
|
||||
|
||||
@@ -140,7 +148,8 @@ public final class SCPDownloadClient extends SCPEngine {
|
||||
return false;
|
||||
}
|
||||
|
||||
private void processDirectory(String dMsg, String tMsg, File f) throws IOException {
|
||||
private void processDirectory(String dMsg, String tMsg, File f)
|
||||
throws IOException {
|
||||
String[] dMsgParts = tokenize(dMsg, 3); // e.g. D0755 0 <dirname>
|
||||
|
||||
long length = parseLong(dMsgParts[1], "dir length");
|
||||
@@ -159,7 +168,8 @@ public final class SCPDownloadClient extends SCPEngine {
|
||||
signal("ACK: E");
|
||||
}
|
||||
|
||||
private void processFile(String cMsg, String tMsg, File f) throws IOException {
|
||||
private void processFile(String cMsg, String tMsg, File f)
|
||||
throws IOException {
|
||||
String[] cMsgParts = tokenize(cMsg, 3);
|
||||
|
||||
long length = parseLong(cMsgParts[1], "length");
|
||||
@@ -178,7 +188,8 @@ public final class SCPDownloadClient extends SCPEngine {
|
||||
signal("Transfer done");
|
||||
}
|
||||
|
||||
private String[] tokenize(String msg, int numPartsExpected) throws IOException {
|
||||
private String[] tokenize(String msg, int numPartsExpected)
|
||||
throws IOException {
|
||||
String[] parts = msg.split(" ");
|
||||
if (parts.length != numPartsExpected)
|
||||
throw new IOException("Could not parse message received from remote SCP: " + msg);
|
||||
|
||||
@@ -33,7 +33,12 @@ import java.util.Queue;
|
||||
abstract class SCPEngine {
|
||||
|
||||
static enum Arg {
|
||||
SOURCE('f'), SINK('t'), RECURSIVE('r'), VERBOSE('v'), PRESERVE_TIMES('p'), QUIET('q');
|
||||
SOURCE('f'),
|
||||
SINK('t'),
|
||||
RECURSIVE('r'),
|
||||
VERBOSE('v'),
|
||||
PRESERVE_TIMES('p'),
|
||||
QUIET('q');
|
||||
|
||||
private final char a;
|
||||
|
||||
@@ -63,7 +68,8 @@ abstract class SCPEngine {
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
public int copy(String sourcePath, String targetPath) throws IOException {
|
||||
public int copy(String sourcePath, String targetPath)
|
||||
throws IOException {
|
||||
cleanSlate();
|
||||
try {
|
||||
startCopy(sourcePath, targetPath);
|
||||
@@ -90,7 +96,8 @@ abstract class SCPEngine {
|
||||
warnings.add(warning);
|
||||
}
|
||||
|
||||
void check(String what) throws IOException {
|
||||
void check(String what)
|
||||
throws IOException {
|
||||
int code = scp.getInputStream().read();
|
||||
switch (code) {
|
||||
case -1:
|
||||
@@ -116,7 +123,8 @@ abstract class SCPEngine {
|
||||
warnings.clear();
|
||||
}
|
||||
|
||||
void execSCPWith(List<Arg> args, String path) throws SSHException {
|
||||
void execSCPWith(List<Arg> args, String path)
|
||||
throws SSHException {
|
||||
StringBuilder cmd = new StringBuilder(SCP_COMMAND);
|
||||
for (Arg arg : args)
|
||||
cmd.append(" ").append(arg);
|
||||
@@ -143,11 +151,13 @@ abstract class SCPEngine {
|
||||
scp = null;
|
||||
}
|
||||
|
||||
String readMessage() throws IOException {
|
||||
String readMessage()
|
||||
throws IOException {
|
||||
return readMessage(true);
|
||||
}
|
||||
|
||||
String readMessage(boolean errOnEOF) throws IOException {
|
||||
String readMessage(boolean errOnEOF)
|
||||
throws IOException {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
int x;
|
||||
while ((x = scp.getInputStream().read()) != LF)
|
||||
@@ -162,22 +172,26 @@ abstract class SCPEngine {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
void sendMessage(String msg) throws IOException {
|
||||
void sendMessage(String msg)
|
||||
throws IOException {
|
||||
log.debug("Sending message: {}", msg);
|
||||
scp.getOutputStream().write((msg + LF).getBytes());
|
||||
scp.getOutputStream().flush();
|
||||
check("Message ACK received");
|
||||
}
|
||||
|
||||
void signal(String what) throws IOException {
|
||||
void signal(String what)
|
||||
throws IOException {
|
||||
log.debug("Signalling: {}", what);
|
||||
scp.getOutputStream().write(0);
|
||||
scp.getOutputStream().flush();
|
||||
}
|
||||
|
||||
abstract void startCopy(String sourcePath, String targetPath) throws IOException;
|
||||
abstract void startCopy(String sourcePath, String targetPath)
|
||||
throws IOException;
|
||||
|
||||
void transfer(InputStream in, OutputStream out, int bufSize, long len) throws IOException {
|
||||
void transfer(InputStream in, OutputStream out, int bufSize, long len)
|
||||
throws IOException {
|
||||
final byte[] buf = new byte[bufSize];
|
||||
long count = 0;
|
||||
int read = 0;
|
||||
|
||||
@@ -17,7 +17,8 @@ package net.schmizz.sshj.xfer.scp;
|
||||
|
||||
import net.schmizz.sshj.common.SSHException;
|
||||
|
||||
public class SCPException extends SSHException {
|
||||
public class SCPException
|
||||
extends SSHException {
|
||||
public SCPException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
@@ -21,7 +21,9 @@ import net.schmizz.sshj.xfer.FileTransfer;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class SCPFileTransfer extends AbstractFileTransfer implements FileTransfer {
|
||||
public class SCPFileTransfer
|
||||
extends AbstractFileTransfer
|
||||
implements FileTransfer {
|
||||
private final SessionFactory sessionFactory;
|
||||
|
||||
public SCPFileTransfer(SessionFactory sessionFactory) {
|
||||
@@ -36,11 +38,13 @@ public class SCPFileTransfer extends AbstractFileTransfer implements FileTransfe
|
||||
return new SCPUploadClient(sessionFactory, getModeGetter());
|
||||
}
|
||||
|
||||
public void download(String remotePath, String localPath) throws IOException {
|
||||
public void download(String remotePath, String localPath)
|
||||
throws IOException {
|
||||
newSCPDownloadClient().copy(remotePath, localPath);
|
||||
}
|
||||
|
||||
public void upload(String localPath, String remotePath) throws IOException {
|
||||
public void upload(String localPath, String remotePath)
|
||||
throws IOException {
|
||||
newSCPUploadClient().copy(localPath, remotePath);
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,8 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/** Support for uploading files over a connected link using SCP. */
|
||||
public final class SCPUploadClient extends SCPEngine {
|
||||
public final class SCPUploadClient
|
||||
extends SCPEngine {
|
||||
|
||||
private final ModeGetter modeGetter;
|
||||
|
||||
@@ -42,7 +43,8 @@ public final class SCPUploadClient extends SCPEngine {
|
||||
|
||||
/** 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 {
|
||||
public synchronized int copy(String sourcePath, String targetPath)
|
||||
throws IOException {
|
||||
return super.copy(sourcePath, targetPath);
|
||||
}
|
||||
|
||||
@@ -51,20 +53,23 @@ public final class SCPUploadClient extends SCPEngine {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected synchronized void startCopy(String sourcePath, String targetPath) throws IOException {
|
||||
protected synchronized void startCopy(String sourcePath, String targetPath)
|
||||
throws IOException {
|
||||
init(targetPath);
|
||||
check("Start status OK");
|
||||
process(new File(sourcePath));
|
||||
}
|
||||
|
||||
private File[] getChildren(File f) throws IOException {
|
||||
private File[] getChildren(File f)
|
||||
throws IOException {
|
||||
File[] files = fileFilter == null ? f.listFiles() : f.listFiles(fileFilter);
|
||||
if (files == null)
|
||||
throw new IOException("Error listing files in directory: " + f);
|
||||
return files;
|
||||
}
|
||||
|
||||
private void init(String target) throws SSHException {
|
||||
private void init(String target)
|
||||
throws SSHException {
|
||||
List<Arg> args = new LinkedList<Arg>();
|
||||
args.add(Arg.SINK);
|
||||
args.add(Arg.RECURSIVE);
|
||||
@@ -73,7 +78,8 @@ public final class SCPUploadClient extends SCPEngine {
|
||||
execSCPWith(args, target);
|
||||
}
|
||||
|
||||
private void process(File f) throws IOException {
|
||||
private void process(File f)
|
||||
throws IOException {
|
||||
if (f.isDirectory())
|
||||
sendDirectory(f);
|
||||
else if (f.isFile())
|
||||
@@ -82,7 +88,8 @@ public final class SCPUploadClient extends SCPEngine {
|
||||
throw new IOException(f + " is not a regular file or directory");
|
||||
}
|
||||
|
||||
private void sendDirectory(File f) throws IOException {
|
||||
private void sendDirectory(File f)
|
||||
throws IOException {
|
||||
log.info("Entering directory `{}`", f.getName());
|
||||
preserveTimeIfPossible(f);
|
||||
sendMessage("D0" + getPermString(f) + " 0 " + f.getName());
|
||||
@@ -94,7 +101,8 @@ public final class SCPUploadClient extends SCPEngine {
|
||||
log.info("Exiting directory `{}`", f.getName());
|
||||
}
|
||||
|
||||
private void sendFile(File f) throws IOException {
|
||||
private void sendFile(File f)
|
||||
throws IOException {
|
||||
log.info("Sending `{}`...", f.getName());
|
||||
preserveTimeIfPossible(f);
|
||||
final InputStream src = new FileInputStream(f);
|
||||
@@ -108,12 +116,14 @@ public final class SCPUploadClient extends SCPEngine {
|
||||
}
|
||||
}
|
||||
|
||||
private void preserveTimeIfPossible(File f) throws IOException {
|
||||
private void preserveTimeIfPossible(File f)
|
||||
throws IOException {
|
||||
if (modeGetter.preservesTimes())
|
||||
sendMessage("T" + modeGetter.getLastModifiedTime(f) + " 0 " + modeGetter.getLastAccessTime(f) + " 0");
|
||||
}
|
||||
|
||||
private String getPermString(File f) throws IOException {
|
||||
private String getPermString(File f)
|
||||
throws IOException {
|
||||
return Integer.toOctalString(modeGetter.getPermissions(f) & 07777);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user