scp/ reformat

This commit is contained in:
Shikhar Bhushan
2010-03-02 00:05:27 +01:00
parent 10067c7baa
commit bc03b01fd1
11 changed files with 107 additions and 51 deletions

View File

@@ -22,7 +22,8 @@ import java.io.IOException;
* Default implementation of {@link ModeGetter} that supplies file permissions as {@code "0644"}, directory permissions * Default implementation of {@link ModeGetter} that supplies file permissions as {@code "0644"}, directory permissions
* as {@code "0755"}, and does not supply mtime and atime. * 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) { public long getLastAccessTime(File f) {
return 0; return 0;
@@ -33,7 +34,8 @@ public class DefaultModeGetter implements ModeGetter {
return 0; return 0;
} }
public int getPermissions(File f) throws IOException { public int getPermissions(File f)
throws IOException {
if (f.isDirectory()) if (f.isDirectory())
return 0755; return 0755;
else if (f.isFile()) else if (f.isFile())

View File

@@ -20,17 +20,21 @@ import java.io.IOException;
/** Default implementation of {@link ModeSetter} that does not set any permissions or preserve mtime and atime. */ /** 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 // 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); // 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 // TODO: set user's rwx permissions; can't do anything about group and world
} }

View File

@@ -19,9 +19,11 @@ import java.io.IOException;
public interface FileTransfer { 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(); ModeGetter getModeGetter();

View File

@@ -20,7 +20,8 @@ import java.io.IOException;
public class FileTransferUtil { 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.exists())
if (f.isDirectory()) { if (f.isDirectory()) {
if (!f.getName().equals(dirname)) if (!f.getName().equals(dirname))
@@ -34,7 +35,8 @@ public class FileTransferUtil {
return f; 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()) if (f.isDirectory())
f = new File(f, filename); f = new File(f, filename);

View File

@@ -30,7 +30,8 @@ public interface ModeGetter {
* *
* @throws IOException * @throws IOException
*/ */
long getLastAccessTime(File f) throws IOException; long getLastAccessTime(File f)
throws IOException;
/** /**
* Returns last modified time for {@code f}. * Returns last modified time for {@code f}.
@@ -41,7 +42,8 @@ public interface ModeGetter {
* *
* @throws IOException * @throws IOException
*/ */
long getLastModifiedTime(File f) throws IOException; long getLastModifiedTime(File f)
throws IOException;
/** /**
* Returns the permissions for {@code f}. * Returns the permissions for {@code f}.
@@ -52,7 +54,8 @@ public interface ModeGetter {
* *
* @throws IOException * @throws IOException
*/ */
int getPermissions(File f) throws IOException; int getPermissions(File f)
throws IOException;
/** Whether this implementation can provide mtime and atime information. */ /** Whether this implementation can provide mtime and atime information. */
boolean preservesTimes(); boolean preservesTimes();

View File

@@ -29,7 +29,8 @@ public interface ModeSetter {
* *
* @throws IOException * @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}. * Set the last modified time for {@code f}.
@@ -39,7 +40,8 @@ public interface ModeSetter {
* *
* @throws IOException * @throws IOException
*/ */
void setLastModifiedTime(File f, long t) throws IOException; void setLastModifiedTime(File f, long t)
throws IOException;
/** /**
* Set the permissions for {@code f}. * Set the permissions for {@code f}.
@@ -49,7 +51,8 @@ public interface ModeSetter {
* *
* @throws IOException * @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. */ /** Whether this implementation is interested in preserving mtime and atime. */
boolean preservesTimes(); boolean preservesTimes();

View File

@@ -28,7 +28,8 @@ import java.util.LinkedList;
import java.util.List; import java.util.List;
/** Support for uploading files over a connected {@link net.schmizz.sshj.SSHClient} link using SCP. */ /** 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; 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. */ /** Download a file from {@code sourcePath} on the connected host to {@code targetPath} locally. */
@Override @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); return super.copy(sourcePath, targetPath);
} }
@@ -54,7 +56,8 @@ public final class SCPDownloadClient extends SCPEngine {
} }
@Override @Override
void startCopy(String sourcePath, String targetPath) throws IOException { void startCopy(String sourcePath, String targetPath)
throws IOException {
init(sourcePath); init(sourcePath);
signal("Start status OK"); signal("Start status OK");
@@ -65,7 +68,8 @@ public final class SCPDownloadClient extends SCPEngine {
while ((msg = readMessage(false)) != null); 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>(); List<Arg> args = new LinkedList<Arg>();
args.add(Arg.SOURCE); args.add(Arg.SOURCE);
args.add(Arg.QUIET); args.add(Arg.QUIET);
@@ -76,7 +80,8 @@ public final class SCPDownloadClient extends SCPEngine {
execSCPWith(args, source); execSCPWith(args, source);
} }
private long parseLong(String longString, String valType) throws SCPException { private long parseLong(String longString, String valType)
throws SCPException {
try { try {
return Long.parseLong(longString); return Long.parseLong(longString);
} catch (NumberFormatException nfe) { } catch (NumberFormatException nfe) {
@@ -86,13 +91,15 @@ public final class SCPDownloadClient extends SCPEngine {
/* e.g. "C0644" -> 0644; "D0755" -> 0755 */ /* e.g. "C0644" -> 0644; "D0755" -> 0755 */
private int parsePermissions(String cmd) throws SCPException { private int parsePermissions(String cmd)
throws SCPException {
if (cmd.length() != 5) if (cmd.length() != 5)
throw new SCPException("Could not parse permissions from `" + cmd + "`"); throw new SCPException("Could not parse permissions from `" + cmd + "`");
return Integer.parseInt(cmd.substring(1), 8); 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); modeSetter.setPermissions(f, perms);
if (tMsg != null && modeSetter.preservesTimes()) { 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) if (msg.length() < 1)
throw new SCPException("Could not parse message `" + msg + "`"); throw new SCPException("Could not parse message `" + msg + "`");
@@ -140,7 +148,8 @@ public final class SCPDownloadClient extends SCPEngine {
return false; 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> String[] dMsgParts = tokenize(dMsg, 3); // e.g. D0755 0 <dirname>
long length = parseLong(dMsgParts[1], "dir length"); long length = parseLong(dMsgParts[1], "dir length");
@@ -159,7 +168,8 @@ public final class SCPDownloadClient extends SCPEngine {
signal("ACK: E"); 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); String[] cMsgParts = tokenize(cMsg, 3);
long length = parseLong(cMsgParts[1], "length"); long length = parseLong(cMsgParts[1], "length");
@@ -178,7 +188,8 @@ public final class SCPDownloadClient extends SCPEngine {
signal("Transfer done"); 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(" "); String[] parts = msg.split(" ");
if (parts.length != numPartsExpected) if (parts.length != numPartsExpected)
throw new IOException("Could not parse message received from remote SCP: " + msg); throw new IOException("Could not parse message received from remote SCP: " + msg);

View File

@@ -33,7 +33,12 @@ import java.util.Queue;
abstract class SCPEngine { abstract class SCPEngine {
static enum Arg { 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; private final char a;
@@ -63,7 +68,8 @@ abstract class SCPEngine {
this.host = host; this.host = host;
} }
public int copy(String sourcePath, String targetPath) throws IOException { public int copy(String sourcePath, String targetPath)
throws IOException {
cleanSlate(); cleanSlate();
try { try {
startCopy(sourcePath, targetPath); startCopy(sourcePath, targetPath);
@@ -90,7 +96,8 @@ abstract class SCPEngine {
warnings.add(warning); warnings.add(warning);
} }
void check(String what) throws IOException { void check(String what)
throws IOException {
int code = scp.getInputStream().read(); int code = scp.getInputStream().read();
switch (code) { switch (code) {
case -1: case -1:
@@ -116,7 +123,8 @@ abstract class SCPEngine {
warnings.clear(); 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); StringBuilder cmd = new StringBuilder(SCP_COMMAND);
for (Arg arg : args) for (Arg arg : args)
cmd.append(" ").append(arg); cmd.append(" ").append(arg);
@@ -143,11 +151,13 @@ abstract class SCPEngine {
scp = null; scp = null;
} }
String readMessage() throws IOException { String readMessage()
throws IOException {
return readMessage(true); return readMessage(true);
} }
String readMessage(boolean errOnEOF) throws IOException { String readMessage(boolean errOnEOF)
throws IOException {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
int x; int x;
while ((x = scp.getInputStream().read()) != LF) while ((x = scp.getInputStream().read()) != LF)
@@ -162,22 +172,26 @@ abstract class SCPEngine {
return sb.toString(); return sb.toString();
} }
void sendMessage(String msg) throws IOException { void sendMessage(String msg)
throws IOException {
log.debug("Sending message: {}", msg); log.debug("Sending message: {}", msg);
scp.getOutputStream().write((msg + LF).getBytes()); scp.getOutputStream().write((msg + LF).getBytes());
scp.getOutputStream().flush(); scp.getOutputStream().flush();
check("Message ACK received"); check("Message ACK received");
} }
void signal(String what) throws IOException { void signal(String what)
throws IOException {
log.debug("Signalling: {}", what); log.debug("Signalling: {}", what);
scp.getOutputStream().write(0); scp.getOutputStream().write(0);
scp.getOutputStream().flush(); 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]; final byte[] buf = new byte[bufSize];
long count = 0; long count = 0;
int read = 0; int read = 0;

View File

@@ -17,7 +17,8 @@ package net.schmizz.sshj.xfer.scp;
import net.schmizz.sshj.common.SSHException; import net.schmizz.sshj.common.SSHException;
public class SCPException extends SSHException { public class SCPException
extends SSHException {
public SCPException(String message) { public SCPException(String message) {
super(message); super(message);
} }

View File

@@ -21,7 +21,9 @@ import net.schmizz.sshj.xfer.FileTransfer;
import java.io.IOException; import java.io.IOException;
public class SCPFileTransfer extends AbstractFileTransfer implements FileTransfer { public class SCPFileTransfer
extends AbstractFileTransfer
implements FileTransfer {
private final SessionFactory sessionFactory; private final SessionFactory sessionFactory;
public SCPFileTransfer(SessionFactory sessionFactory) { public SCPFileTransfer(SessionFactory sessionFactory) {
@@ -36,11 +38,13 @@ public class SCPFileTransfer extends AbstractFileTransfer implements FileTransfe
return new SCPUploadClient(sessionFactory, getModeGetter()); 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); 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); newSCPUploadClient().copy(localPath, remotePath);
} }

View File

@@ -29,7 +29,8 @@ import java.util.LinkedList;
import java.util.List; import java.util.List;
/** Support for uploading files over a connected link using SCP. */ /** 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; 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. */ /** Upload a file from {@code sourcePath} locally to {@code targetPath} on the remote host. */
@Override @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); return super.copy(sourcePath, targetPath);
} }
@@ -51,20 +53,23 @@ public final class SCPUploadClient extends SCPEngine {
} }
@Override @Override
protected synchronized void startCopy(String sourcePath, String targetPath) throws IOException { protected synchronized void startCopy(String sourcePath, String targetPath)
throws IOException {
init(targetPath); init(targetPath);
check("Start status OK"); check("Start status OK");
process(new File(sourcePath)); 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); File[] files = fileFilter == null ? f.listFiles() : f.listFiles(fileFilter);
if (files == null) if (files == null)
throw new IOException("Error listing files in directory: " + f); throw new IOException("Error listing files in directory: " + f);
return files; return files;
} }
private void init(String target) throws SSHException { private void init(String target)
throws SSHException {
List<Arg> args = new LinkedList<Arg>(); List<Arg> args = new LinkedList<Arg>();
args.add(Arg.SINK); args.add(Arg.SINK);
args.add(Arg.RECURSIVE); args.add(Arg.RECURSIVE);
@@ -73,7 +78,8 @@ public final class SCPUploadClient extends SCPEngine {
execSCPWith(args, target); execSCPWith(args, target);
} }
private void process(File f) throws IOException { private void process(File f)
throws IOException {
if (f.isDirectory()) if (f.isDirectory())
sendDirectory(f); sendDirectory(f);
else if (f.isFile()) 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"); 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()); log.info("Entering directory `{}`", f.getName());
preserveTimeIfPossible(f); preserveTimeIfPossible(f);
sendMessage("D0" + getPermString(f) + " 0 " + f.getName()); sendMessage("D0" + getPermString(f) + " 0 " + f.getName());
@@ -94,7 +101,8 @@ public final class SCPUploadClient extends SCPEngine {
log.info("Exiting directory `{}`", f.getName()); 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()); log.info("Sending `{}`...", f.getName());
preserveTimeIfPossible(f); preserveTimeIfPossible(f);
final InputStream src = new FileInputStream(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()) if (modeGetter.preservesTimes())
sendMessage("T" + modeGetter.getLastModifiedTime(f) + " 0 " + modeGetter.getLastAccessTime(f) + " 0"); 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); return Integer.toOctalString(modeGetter.getPermissions(f) & 07777);
} }