mirror of
https://github.com/hierynomus/sshj.git
synced 2025-12-06 15:20:54 +03:00
sftp reformat
This commit is contained in:
@@ -27,7 +27,11 @@ public final class FileAttributes {
|
||||
|
||||
public static enum Flag {
|
||||
|
||||
SIZE(0x00000001), UIDGID(0x00000002), MODE(0x00000004), ACMODTIME(0x00000008), EXTENDED(0x80000000);
|
||||
SIZE(0x00000001),
|
||||
UIDGID(0x00000002),
|
||||
MODE(0x00000004),
|
||||
ACMODTIME(0x00000008),
|
||||
EXTENDED(0x80000000);
|
||||
|
||||
private final int flag;
|
||||
|
||||
|
||||
@@ -24,7 +24,8 @@ import java.io.InputStream;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class PacketReader extends Thread {
|
||||
public class PacketReader
|
||||
extends Thread {
|
||||
|
||||
/** Logger */
|
||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||
@@ -39,7 +40,8 @@ public class PacketReader extends Thread {
|
||||
setName("sftp reader");
|
||||
}
|
||||
|
||||
private void readIntoBuffer(byte[] buf, int off, int len) throws IOException {
|
||||
private void readIntoBuffer(byte[] buf, int off, int len)
|
||||
throws IOException {
|
||||
int count = 0;
|
||||
int read = 0;
|
||||
while (count < len && ((read = in.read(buf, off + count, len - count)) != -1))
|
||||
@@ -48,17 +50,18 @@ public class PacketReader extends Thread {
|
||||
throw new SFTPException("EOF while reading packet");
|
||||
}
|
||||
|
||||
private int getPacketLength() throws IOException {
|
||||
private int getPacketLength()
|
||||
throws IOException {
|
||||
readIntoBuffer(lenBuf, 0, lenBuf.length);
|
||||
|
||||
return (int) (lenBuf[0] << 24 & 0xff000000L
|
||||
| lenBuf[1] << 16 & 0x00ff0000L
|
||||
| lenBuf[2] << 8 & 0x0000ff00L
|
||||
| lenBuf[3] & 0x000000ffL
|
||||
);
|
||||
| lenBuf[1] << 16 & 0x00ff0000L
|
||||
| lenBuf[2] << 8 & 0x0000ff00L
|
||||
| lenBuf[3] & 0x000000ffL);
|
||||
}
|
||||
|
||||
public SFTPPacket<Response> readPacket() throws IOException {
|
||||
public SFTPPacket<Response> readPacket()
|
||||
throws IOException {
|
||||
int len = getPacketLength();
|
||||
|
||||
packet.rpos(0);
|
||||
@@ -85,13 +88,14 @@ public class PacketReader extends Thread {
|
||||
}
|
||||
}
|
||||
|
||||
public void handle() throws SFTPException {
|
||||
public void handle()
|
||||
throws SFTPException {
|
||||
Response resp = new Response(packet);
|
||||
Future<Response, SFTPException> future = futures.remove(resp.getRequestID());
|
||||
log.debug("Received {} packet", resp.getType());
|
||||
if (future == null)
|
||||
throw new SFTPException("Received [" + resp.readType() + "] response for request-id " + resp.getRequestID()
|
||||
+ ", no such request was made");
|
||||
+ ", no such request was made");
|
||||
else
|
||||
future.set(resp);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ class PathComponents {
|
||||
|
||||
public static String adjustForParent(String parent, String path) {
|
||||
return (path.startsWith("/")) ? path // Absolute path, nothing to adjust
|
||||
: (parent + (parent.endsWith("/") ? "" : "/") + path); // Relative path
|
||||
: (parent + (parent.endsWith("/") ? "" : "/") + path); // Relative path
|
||||
}
|
||||
|
||||
private static String trimFinalSlash(String path) {
|
||||
|
||||
@@ -26,7 +26,8 @@ class PathHelper {
|
||||
this.sftp = sftp;
|
||||
}
|
||||
|
||||
public PathComponents getComponents(String path) throws IOException {
|
||||
public PathComponents getComponents(String path)
|
||||
throws IOException {
|
||||
if (path.isEmpty() || path.equals("."))
|
||||
return getComponents(getDotDir());
|
||||
|
||||
@@ -48,11 +49,13 @@ class PathHelper {
|
||||
}
|
||||
}
|
||||
|
||||
private String getDotDir() throws IOException {
|
||||
private String getDotDir()
|
||||
throws IOException {
|
||||
return (dotDir != null) ? dotDir : (dotDir = canon("."));
|
||||
}
|
||||
|
||||
private String canon(String path) throws IOException {
|
||||
private String canon(String path)
|
||||
throws IOException {
|
||||
return sftp.canonicalize(path);
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,8 @@ import java.io.DataOutputStream;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
|
||||
public class RandomAccessRemoteFile implements DataInput, DataOutput {
|
||||
public class RandomAccessRemoteFile
|
||||
implements DataInput, DataOutput {
|
||||
|
||||
|
||||
private final byte[] singleByte = new byte[1];
|
||||
@@ -43,35 +44,41 @@ public class RandomAccessRemoteFile implements DataInput, DataOutput {
|
||||
this.fp = fp;
|
||||
}
|
||||
|
||||
public int read() throws IOException {
|
||||
public int read()
|
||||
throws IOException {
|
||||
return read(singleByte, 0, 1) == -1 ? -1 : singleByte[0];
|
||||
}
|
||||
|
||||
public int read(byte[] b) throws IOException {
|
||||
public int read(byte[] b)
|
||||
throws IOException {
|
||||
return read(b, 0, b.length);
|
||||
}
|
||||
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
public int read(byte[] b, int off, int len)
|
||||
throws IOException {
|
||||
final int count = rf.read(fp, b, off, len);
|
||||
fp += count;
|
||||
return count;
|
||||
}
|
||||
|
||||
public boolean readBoolean() throws IOException {
|
||||
public boolean readBoolean()
|
||||
throws IOException {
|
||||
final int ch = read();
|
||||
if (ch < 0)
|
||||
throw new EOFException();
|
||||
return (ch != 0);
|
||||
}
|
||||
|
||||
public byte readByte() throws IOException {
|
||||
public byte readByte()
|
||||
throws IOException {
|
||||
final int ch = this.read();
|
||||
if (ch < 0)
|
||||
throw new EOFException();
|
||||
return (byte) (ch);
|
||||
}
|
||||
|
||||
public char readChar() throws IOException {
|
||||
public char readChar()
|
||||
throws IOException {
|
||||
final int ch1 = this.read();
|
||||
final int ch2 = this.read();
|
||||
if ((ch1 | ch2) < 0)
|
||||
@@ -79,19 +86,23 @@ public class RandomAccessRemoteFile implements DataInput, DataOutput {
|
||||
return (char) ((ch1 << 8) + ch2);
|
||||
}
|
||||
|
||||
public double readDouble() throws IOException {
|
||||
public double readDouble()
|
||||
throws IOException {
|
||||
return Double.longBitsToDouble(readLong());
|
||||
}
|
||||
|
||||
public float readFloat() throws IOException {
|
||||
public float readFloat()
|
||||
throws IOException {
|
||||
return Float.intBitsToFloat(readInt());
|
||||
}
|
||||
|
||||
public void readFully(byte[] b) throws IOException {
|
||||
public void readFully(byte[] b)
|
||||
throws IOException {
|
||||
readFully(b, 0, b.length);
|
||||
}
|
||||
|
||||
public void readFully(byte[] b, int off, int len) throws IOException {
|
||||
public void readFully(byte[] b, int off, int len)
|
||||
throws IOException {
|
||||
int n = 0;
|
||||
do {
|
||||
int count = read(b, off + n, len - n);
|
||||
@@ -101,7 +112,8 @@ public class RandomAccessRemoteFile implements DataInput, DataOutput {
|
||||
} while (n < len);
|
||||
}
|
||||
|
||||
public int readInt() throws IOException {
|
||||
public int readInt()
|
||||
throws IOException {
|
||||
final int ch1 = read();
|
||||
final int ch2 = read();
|
||||
final int ch3 = read();
|
||||
@@ -111,7 +123,8 @@ public class RandomAccessRemoteFile implements DataInput, DataOutput {
|
||||
return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + ch4);
|
||||
}
|
||||
|
||||
public String readLine() throws IOException {
|
||||
public String readLine()
|
||||
throws IOException {
|
||||
StringBuffer input = new StringBuffer();
|
||||
int c = -1;
|
||||
boolean eol = false;
|
||||
@@ -138,11 +151,13 @@ public class RandomAccessRemoteFile implements DataInput, DataOutput {
|
||||
return input.toString();
|
||||
}
|
||||
|
||||
public long readLong() throws IOException {
|
||||
public long readLong()
|
||||
throws IOException {
|
||||
return ((long) (readInt()) << 32) + (readInt() & 0xFFFFFFFFL);
|
||||
}
|
||||
|
||||
public short readShort() throws IOException {
|
||||
public short readShort()
|
||||
throws IOException {
|
||||
final int ch1 = this.read();
|
||||
final int ch2 = this.read();
|
||||
if ((ch1 | ch2) < 0)
|
||||
@@ -150,18 +165,21 @@ public class RandomAccessRemoteFile implements DataInput, DataOutput {
|
||||
return (short) ((ch1 << 8) + ch2);
|
||||
}
|
||||
|
||||
public String readUTF() throws IOException {
|
||||
public String readUTF()
|
||||
throws IOException {
|
||||
return DataInputStream.readUTF(this);
|
||||
}
|
||||
|
||||
public int readUnsignedByte() throws IOException {
|
||||
public int readUnsignedByte()
|
||||
throws IOException {
|
||||
final int ch = this.read();
|
||||
if (ch < 0)
|
||||
throw new EOFException();
|
||||
return ch;
|
||||
}
|
||||
|
||||
public int readUnsignedShort() throws IOException {
|
||||
public int readUnsignedShort()
|
||||
throws IOException {
|
||||
final int ch1 = this.read();
|
||||
final int ch2 = this.read();
|
||||
if ((ch1 | ch2) < 0)
|
||||
@@ -169,7 +187,8 @@ public class RandomAccessRemoteFile implements DataInput, DataOutput {
|
||||
return (ch1 << 8) + ch2;
|
||||
}
|
||||
|
||||
public int skipBytes(int n) throws IOException {
|
||||
public int skipBytes(int n)
|
||||
throws IOException {
|
||||
if (n <= 0)
|
||||
return 0;
|
||||
final long pos = getFilePointer();
|
||||
@@ -183,39 +202,47 @@ public class RandomAccessRemoteFile implements DataInput, DataOutput {
|
||||
return (int) (newpos - pos);
|
||||
}
|
||||
|
||||
public void write(int i) throws IOException {
|
||||
public void write(int i)
|
||||
throws IOException {
|
||||
singleByte[0] = (byte) i;
|
||||
write(singleByte);
|
||||
}
|
||||
|
||||
public void write(byte[] b) throws IOException {
|
||||
public void write(byte[] b)
|
||||
throws IOException {
|
||||
write(b, 0, b.length);
|
||||
}
|
||||
|
||||
public void write(byte[] b, int off, int len) throws IOException {
|
||||
public void write(byte[] b, int off, int len)
|
||||
throws IOException {
|
||||
rf.write(fp, b, off, len);
|
||||
fp += (len - off);
|
||||
}
|
||||
|
||||
public void writeBoolean(boolean v) throws IOException {
|
||||
public void writeBoolean(boolean v)
|
||||
throws IOException {
|
||||
write(v ? 1 : 0);
|
||||
}
|
||||
|
||||
public void writeByte(int v) throws IOException {
|
||||
public void writeByte(int v)
|
||||
throws IOException {
|
||||
write(v);
|
||||
}
|
||||
|
||||
public void writeBytes(String s) throws IOException {
|
||||
public void writeBytes(String s)
|
||||
throws IOException {
|
||||
final byte[] b = s.getBytes();
|
||||
write(b, 0, b.length);
|
||||
}
|
||||
|
||||
public void writeChar(int v) throws IOException {
|
||||
public void writeChar(int v)
|
||||
throws IOException {
|
||||
write((v >>> 8) & 0xFF);
|
||||
write(v & 0xFF);
|
||||
}
|
||||
|
||||
public void writeChars(String s) throws IOException {
|
||||
public void writeChars(String s)
|
||||
throws IOException {
|
||||
final int clen = s.length();
|
||||
final int blen = 2 * clen;
|
||||
final byte[] b = new byte[blen];
|
||||
@@ -228,22 +255,26 @@ public class RandomAccessRemoteFile implements DataInput, DataOutput {
|
||||
write(b, 0, blen);
|
||||
}
|
||||
|
||||
public void writeDouble(double v) throws IOException {
|
||||
public void writeDouble(double v)
|
||||
throws IOException {
|
||||
writeLong(Double.doubleToLongBits(v));
|
||||
}
|
||||
|
||||
public void writeFloat(float v) throws IOException {
|
||||
public void writeFloat(float v)
|
||||
throws IOException {
|
||||
writeInt(Float.floatToIntBits(v));
|
||||
}
|
||||
|
||||
public void writeInt(int v) throws IOException {
|
||||
public void writeInt(int v)
|
||||
throws IOException {
|
||||
write((v >>> 24) & 0xFF);
|
||||
write((v >>> 16) & 0xFF);
|
||||
write((v >>> 8) & 0xFF);
|
||||
write(v & 0xFF);
|
||||
}
|
||||
|
||||
public void writeLong(long v) throws IOException {
|
||||
public void writeLong(long v)
|
||||
throws IOException {
|
||||
write((int) (v >>> 56) & 0xFF);
|
||||
write((int) (v >>> 48) & 0xFF);
|
||||
write((int) (v >>> 40) & 0xFF);
|
||||
@@ -254,12 +285,14 @@ public class RandomAccessRemoteFile implements DataInput, DataOutput {
|
||||
write((int) v & 0xFF);
|
||||
}
|
||||
|
||||
public void writeShort(int v) throws IOException {
|
||||
public void writeShort(int v)
|
||||
throws IOException {
|
||||
write((v >>> 8) & 0xFF);
|
||||
write(v & 0xFF);
|
||||
}
|
||||
|
||||
public void writeUTF(String str) throws IOException {
|
||||
public void writeUTF(String str)
|
||||
throws IOException {
|
||||
final DataOutputStream dos = new DataOutputStream(rf.new RemoteFileOutputStream(fp));
|
||||
try {
|
||||
dos.writeUTF(str);
|
||||
|
||||
@@ -21,13 +21,15 @@ import java.io.IOException;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class RemoteDirectory extends RemoteResource {
|
||||
public class RemoteDirectory
|
||||
extends RemoteResource {
|
||||
|
||||
public RemoteDirectory(Requester requester, String path, String handle) {
|
||||
super(requester, path, handle);
|
||||
}
|
||||
|
||||
public List<RemoteResourceInfo> scan(RemoteResourceFilter filter) throws IOException {
|
||||
public List<RemoteResourceInfo> scan(RemoteResourceFilter filter)
|
||||
throws IOException {
|
||||
List<RemoteResourceInfo> rri = new LinkedList<RemoteResourceInfo>();
|
||||
loop:
|
||||
for (; ;) {
|
||||
|
||||
@@ -21,7 +21,8 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class RemoteFile extends RemoteResource {
|
||||
public class RemoteFile
|
||||
extends RemoteResource {
|
||||
|
||||
public RemoteFile(Requester requester, String path, String handle) {
|
||||
super(requester, path, handle);
|
||||
@@ -35,21 +36,25 @@ public class RemoteFile extends RemoteResource {
|
||||
return new RemoteFileOutputStream();
|
||||
}
|
||||
|
||||
public FileAttributes fetchAttributes() throws IOException {
|
||||
public FileAttributes fetchAttributes()
|
||||
throws IOException {
|
||||
return requester.doRequest(newRequest(PacketType.FSTAT)) //
|
||||
.ensurePacketTypeIs(PacketType.ATTRS) //
|
||||
.readFileAttributes();
|
||||
}
|
||||
|
||||
public long length() throws IOException {
|
||||
public long length()
|
||||
throws IOException {
|
||||
return fetchAttributes().getSize();
|
||||
}
|
||||
|
||||
public void setLength(long len) throws IOException {
|
||||
public void setLength(long len)
|
||||
throws IOException {
|
||||
setAttributes(new FileAttributes.Builder().withSize(len).build());
|
||||
}
|
||||
|
||||
public int read(long fileOffset, byte[] to, int offset, int len) throws IOException {
|
||||
public int read(long fileOffset, byte[] to, int offset, int len)
|
||||
throws IOException {
|
||||
Response res = requester.doRequest(newRequest(PacketType.READ).putUINT64(fileOffset).putInt(len));
|
||||
switch (res.getType()) {
|
||||
case DATA:
|
||||
@@ -66,30 +71,33 @@ public class RemoteFile extends RemoteResource {
|
||||
}
|
||||
}
|
||||
|
||||
public void write(long fileOffset, byte[] data, int off, int len) throws IOException {
|
||||
public void write(long fileOffset, byte[] data, int off, int len)
|
||||
throws IOException {
|
||||
requester.doRequest( //
|
||||
newRequest(PacketType.WRITE) //
|
||||
.putUINT64(fileOffset) //
|
||||
.putInt(len - off) //
|
||||
.putRawBytes(data, off, len) //
|
||||
newRequest(PacketType.WRITE) //
|
||||
.putUINT64(fileOffset) //
|
||||
.putInt(len - off) //
|
||||
.putRawBytes(data, off, len) //
|
||||
).ensureStatusPacketIsOK();
|
||||
}
|
||||
|
||||
public void setAttributes(FileAttributes attrs) throws IOException {
|
||||
public void setAttributes(FileAttributes attrs)
|
||||
throws IOException {
|
||||
requester.doRequest(newRequest(PacketType.FSETSTAT).putFileAttributes(attrs)).ensureStatusPacketIsOK();
|
||||
}
|
||||
|
||||
public int getOutgoingPacketOverhead() {
|
||||
return 1 + // packet type
|
||||
4 + // request id
|
||||
4 + // next length
|
||||
handle.length() + // next
|
||||
8 + // file offset
|
||||
4 + // data length
|
||||
4; // packet length
|
||||
4 + // request id
|
||||
4 + // next length
|
||||
handle.length() + // next
|
||||
8 + // file offset
|
||||
4 + // data length
|
||||
4; // packet length
|
||||
}
|
||||
|
||||
public class RemoteFileOutputStream extends OutputStream {
|
||||
public class RemoteFileOutputStream
|
||||
extends OutputStream {
|
||||
|
||||
|
||||
private final byte[] b = new byte[1];
|
||||
@@ -105,20 +113,23 @@ public class RemoteFile extends RemoteResource {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(int w) throws IOException {
|
||||
public void write(int w)
|
||||
throws IOException {
|
||||
b[0] = (byte) w;
|
||||
write(b, 0, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] buf, int off, int len) throws IOException {
|
||||
public void write(byte[] buf, int off, int len)
|
||||
throws IOException {
|
||||
RemoteFile.this.write(fileOffset, buf, off, len);
|
||||
fileOffset += len;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class RemoteFileInputStream extends InputStream {
|
||||
public class RemoteFileInputStream
|
||||
extends InputStream {
|
||||
|
||||
private final byte[] b = new byte[1];
|
||||
|
||||
@@ -146,22 +157,26 @@ public class RemoteFile extends RemoteResource {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() throws IOException {
|
||||
public void reset()
|
||||
throws IOException {
|
||||
fileOffset = markPos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long skip(long n) throws IOException {
|
||||
public long skip(long n)
|
||||
throws IOException {
|
||||
return (this.fileOffset = Math.min(fileOffset + n, length()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
public int read()
|
||||
throws IOException {
|
||||
return read(b, 0, 1) == -1 ? -1 : b[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] into, int off, int len) throws IOException {
|
||||
public int read(byte[] into, int off, int len)
|
||||
throws IOException {
|
||||
int read = RemoteFile.this.read(fileOffset, into, off, len);
|
||||
if (read != -1) {
|
||||
fileOffset += read;
|
||||
|
||||
@@ -21,7 +21,8 @@ import org.slf4j.LoggerFactory;
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
|
||||
abstract class RemoteResource implements Closeable {
|
||||
abstract class RemoteResource
|
||||
implements Closeable {
|
||||
|
||||
/** Logger */
|
||||
protected final Logger log = LoggerFactory.getLogger(getClass());
|
||||
@@ -44,7 +45,8 @@ abstract class RemoteResource implements Closeable {
|
||||
return requester.newRequest(type).putString(handle);
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
public void close()
|
||||
throws IOException {
|
||||
log.info("Closing `{}`", this);
|
||||
requester.doRequest(newRequest(PacketType.CLOSE)).ensureStatusPacketIsOK();
|
||||
}
|
||||
|
||||
@@ -17,7 +17,8 @@ package net.schmizz.sshj.sftp;
|
||||
|
||||
import net.schmizz.concurrent.Future;
|
||||
|
||||
public class Request extends SFTPPacket<Request> {
|
||||
public class Request
|
||||
extends SFTPPacket<Request> {
|
||||
|
||||
private final PacketType type;
|
||||
private final long reqID;
|
||||
|
||||
@@ -21,6 +21,7 @@ public interface Requester {
|
||||
|
||||
Request newRequest(PacketType type);
|
||||
|
||||
Response doRequest(Request req) throws IOException;
|
||||
Response doRequest(Request req)
|
||||
throws IOException;
|
||||
|
||||
}
|
||||
|
||||
@@ -17,7 +17,8 @@ package net.schmizz.sshj.sftp;
|
||||
|
||||
import net.schmizz.sshj.common.Buffer;
|
||||
|
||||
public class Response extends SFTPPacket<Response> {
|
||||
public class Response
|
||||
extends SFTPPacket<Response> {
|
||||
|
||||
public static enum StatusCode {
|
||||
UNKNOWN(-1),
|
||||
@@ -67,7 +68,8 @@ public class Response extends SFTPPacket<Response> {
|
||||
return StatusCode.fromInt(readInt());
|
||||
}
|
||||
|
||||
public Response ensurePacketTypeIs(PacketType pt) throws SFTPException {
|
||||
public Response ensurePacketTypeIs(PacketType pt)
|
||||
throws SFTPException {
|
||||
if (getType() != pt)
|
||||
if (getType() == PacketType.STATUS)
|
||||
throw new SFTPException(readStatusCode(), readString());
|
||||
@@ -76,11 +78,13 @@ public class Response extends SFTPPacket<Response> {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Response ensureStatusPacketIsOK() throws SFTPException {
|
||||
public Response ensureStatusPacketIsOK()
|
||||
throws SFTPException {
|
||||
return ensurePacketTypeIs(PacketType.STATUS).ensureStatusIs(StatusCode.OK);
|
||||
}
|
||||
|
||||
public Response ensureStatusIs(StatusCode acceptable) throws SFTPException {
|
||||
public Response ensureStatusIs(StatusCode acceptable)
|
||||
throws SFTPException {
|
||||
StatusCode sc = readStatusCode();
|
||||
if (sc != acceptable)
|
||||
throw new SFTPException(sc, readString());
|
||||
|
||||
@@ -33,7 +33,8 @@ public class SFTPClient {
|
||||
private final SFTPEngine sftp;
|
||||
private final SFTPFileTransfer xfer;
|
||||
|
||||
public SFTPClient(SessionFactory ssh) throws IOException {
|
||||
public SFTPClient(SessionFactory ssh)
|
||||
throws IOException {
|
||||
this.sftp = new SFTPEngine(ssh).init();
|
||||
this.xfer = new SFTPFileTransfer(sftp);
|
||||
}
|
||||
@@ -46,11 +47,13 @@ public class SFTPClient {
|
||||
return xfer;
|
||||
}
|
||||
|
||||
public List<RemoteResourceInfo> ls(String path) throws IOException {
|
||||
public List<RemoteResourceInfo> ls(String path)
|
||||
throws IOException {
|
||||
return ls(path, null);
|
||||
}
|
||||
|
||||
public List<RemoteResourceInfo> ls(String path, RemoteResourceFilter filter) throws IOException {
|
||||
public List<RemoteResourceInfo> ls(String path, RemoteResourceFilter filter)
|
||||
throws IOException {
|
||||
final RemoteDirectory dir = sftp.openDir(path);
|
||||
try {
|
||||
return dir.scan(filter);
|
||||
@@ -59,36 +62,44 @@ public class SFTPClient {
|
||||
}
|
||||
}
|
||||
|
||||
public RemoteFile open(String filename, Set<OpenMode> mode, FileAttributes attrs) throws IOException {
|
||||
public RemoteFile open(String filename, Set<OpenMode> mode, FileAttributes attrs)
|
||||
throws IOException {
|
||||
log.debug("Opening `{}`", filename);
|
||||
return sftp.open(filename, mode, attrs);
|
||||
}
|
||||
|
||||
public RemoteFile open(String filename, Set<OpenMode> mode) throws IOException {
|
||||
public RemoteFile open(String filename, Set<OpenMode> mode)
|
||||
throws IOException {
|
||||
return open(filename, mode, new FileAttributes());
|
||||
}
|
||||
|
||||
public RemoteFile open(String filename) throws IOException {
|
||||
public RemoteFile open(String filename)
|
||||
throws IOException {
|
||||
return open(filename, EnumSet.of(OpenMode.READ));
|
||||
}
|
||||
|
||||
public void mkdir(String dirname) throws IOException {
|
||||
public void mkdir(String dirname)
|
||||
throws IOException {
|
||||
sftp.makeDir(dirname);
|
||||
}
|
||||
|
||||
public void rename(String oldpath, String newpath) throws IOException {
|
||||
public void rename(String oldpath, String newpath)
|
||||
throws IOException {
|
||||
sftp.rename(oldpath, newpath);
|
||||
}
|
||||
|
||||
public void rm(String filename) throws IOException {
|
||||
public void rm(String filename)
|
||||
throws IOException {
|
||||
sftp.remove(filename);
|
||||
}
|
||||
|
||||
public void rmdir(String dirname) throws IOException {
|
||||
public void rmdir(String dirname)
|
||||
throws IOException {
|
||||
sftp.removeDir(dirname);
|
||||
}
|
||||
|
||||
public void symlink(String linkpath, String targetpath) throws IOException {
|
||||
public void symlink(String linkpath, String targetpath)
|
||||
throws IOException {
|
||||
sftp.symlink(linkpath, targetpath);
|
||||
}
|
||||
|
||||
@@ -96,79 +107,98 @@ public class SFTPClient {
|
||||
return sftp.getOperativeProtocolVersion();
|
||||
}
|
||||
|
||||
public void setattr(String path, FileAttributes attrs) throws IOException {
|
||||
public void setattr(String path, FileAttributes attrs)
|
||||
throws IOException {
|
||||
sftp.setAttributes(path, attrs);
|
||||
}
|
||||
|
||||
public int uid(String path) throws IOException {
|
||||
public int uid(String path)
|
||||
throws IOException {
|
||||
return stat(path).getUID();
|
||||
}
|
||||
|
||||
public int gid(String path) throws IOException {
|
||||
public int gid(String path)
|
||||
throws IOException {
|
||||
return stat(path).getGID();
|
||||
}
|
||||
|
||||
public long atime(String path) throws IOException {
|
||||
public long atime(String path)
|
||||
throws IOException {
|
||||
return stat(path).getAtime();
|
||||
}
|
||||
|
||||
public long mtime(String path) throws IOException {
|
||||
public long mtime(String path)
|
||||
throws IOException {
|
||||
return stat(path).getMtime();
|
||||
}
|
||||
|
||||
public Set<FilePermission> perms(String path) throws IOException {
|
||||
public Set<FilePermission> perms(String path)
|
||||
throws IOException {
|
||||
return stat(path).getPermissions();
|
||||
}
|
||||
|
||||
public FileMode mode(String path) throws IOException {
|
||||
public FileMode mode(String path)
|
||||
throws IOException {
|
||||
return stat(path).getMode();
|
||||
}
|
||||
|
||||
public FileMode.Type type(String path) throws IOException {
|
||||
public FileMode.Type type(String path)
|
||||
throws IOException {
|
||||
return stat(path).getType();
|
||||
}
|
||||
|
||||
public String readlink(String path) throws IOException {
|
||||
public String readlink(String path)
|
||||
throws IOException {
|
||||
return sftp.readLink(path);
|
||||
}
|
||||
|
||||
public FileAttributes stat(String path) throws IOException {
|
||||
public FileAttributes stat(String path)
|
||||
throws IOException {
|
||||
return sftp.stat(path);
|
||||
}
|
||||
|
||||
public FileAttributes lstat(String path) throws IOException {
|
||||
public FileAttributes lstat(String path)
|
||||
throws IOException {
|
||||
return sftp.lstat(path);
|
||||
}
|
||||
|
||||
public void chown(String path, int uid) throws IOException {
|
||||
public void chown(String path, int uid)
|
||||
throws IOException {
|
||||
setattr(path, new FileAttributes.Builder().withUIDGID(uid, gid(path)).build());
|
||||
}
|
||||
|
||||
public void chmod(String path, int perms) throws IOException {
|
||||
public void chmod(String path, int perms)
|
||||
throws IOException {
|
||||
setattr(path, new FileAttributes.Builder().withPermissions(perms).build());
|
||||
}
|
||||
|
||||
public void chgrp(String path, int gid) throws IOException {
|
||||
public void chgrp(String path, int gid)
|
||||
throws IOException {
|
||||
setattr(path, new FileAttributes.Builder().withUIDGID(uid(path), gid).build());
|
||||
}
|
||||
|
||||
public void truncate(String path, long size) throws IOException {
|
||||
public void truncate(String path, long size)
|
||||
throws IOException {
|
||||
setattr(path, new FileAttributes.Builder().withSize(size).build());
|
||||
}
|
||||
|
||||
public String canonicalize(String path) throws IOException {
|
||||
public String canonicalize(String path)
|
||||
throws IOException {
|
||||
return sftp.canonicalize(path);
|
||||
}
|
||||
|
||||
public long size(String path) throws IOException {
|
||||
public long size(String path)
|
||||
throws IOException {
|
||||
return stat(path).getSize();
|
||||
}
|
||||
|
||||
public void get(String source, String dest) throws IOException {
|
||||
public void get(String source, String dest)
|
||||
throws IOException {
|
||||
xfer.download(source, dest);
|
||||
}
|
||||
|
||||
public void put(String source, String dest) throws IOException {
|
||||
public void put(String source, String dest)
|
||||
throws IOException {
|
||||
xfer.upload(source, dest);
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,8 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class SFTPEngine implements Requester {
|
||||
public class SFTPEngine
|
||||
implements Requester {
|
||||
|
||||
/** Logger */
|
||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||
@@ -48,7 +49,8 @@ public class SFTPEngine implements Requester {
|
||||
private int negotiatedVersion;
|
||||
private final Map<String, String> serverExtensions = new HashMap<String, String>();
|
||||
|
||||
public SFTPEngine(SessionFactory ssh) throws SSHException {
|
||||
public SFTPEngine(SessionFactory ssh)
|
||||
throws SSHException {
|
||||
sub = ssh.startSession().startSubsystem("sftp");
|
||||
out = sub.getOutputStream();
|
||||
reader = new PacketReader(sub.getInputStream());
|
||||
@@ -58,7 +60,8 @@ public class SFTPEngine implements Requester {
|
||||
return sub;
|
||||
}
|
||||
|
||||
public SFTPEngine init() throws IOException {
|
||||
public SFTPEngine init()
|
||||
throws IOException {
|
||||
transmit(new SFTPPacket<Request>(PacketType.INIT).putInt(PROTOCOL_VERSION));
|
||||
|
||||
final SFTPPacket<Response> response = reader.readPacket();
|
||||
@@ -88,14 +91,16 @@ public class SFTPEngine implements Requester {
|
||||
return new Request(type, reqID = reqID + 1 & 0xffffffffL);
|
||||
}
|
||||
|
||||
public Response doRequest(Request req) throws IOException {
|
||||
public Response doRequest(Request req)
|
||||
throws IOException {
|
||||
reader.expectResponseTo(req);
|
||||
log.debug("Sending {}", req);
|
||||
transmit(req);
|
||||
return req.getResponseFuture().get(timeout, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
private synchronized void transmit(SFTPPacket<Request> payload) throws IOException {
|
||||
private synchronized void transmit(SFTPPacket<Request> payload)
|
||||
throws IOException {
|
||||
final int len = payload.available();
|
||||
out.write((len >>> 24) & 0xff);
|
||||
out.write((len >>> 16) & 0xff);
|
||||
@@ -105,7 +110,8 @@ public class SFTPEngine implements Requester {
|
||||
out.flush();
|
||||
}
|
||||
|
||||
public RemoteFile open(String path, Set<OpenMode> modes, FileAttributes fa) throws IOException {
|
||||
public RemoteFile open(String path, Set<OpenMode> modes, FileAttributes fa)
|
||||
throws IOException {
|
||||
|
||||
final String handle = doRequest(
|
||||
newRequest(PacketType.OPEN).putString(path).putInt(OpenMode.toMask(modes)).putFileAttributes(fa)
|
||||
@@ -113,90 +119,106 @@ public class SFTPEngine implements Requester {
|
||||
return new RemoteFile(this, path, handle);
|
||||
}
|
||||
|
||||
public RemoteFile open(String filename, Set<OpenMode> modes) throws IOException {
|
||||
public RemoteFile open(String filename, Set<OpenMode> modes)
|
||||
throws IOException {
|
||||
return open(filename, modes, new FileAttributes());
|
||||
}
|
||||
|
||||
public RemoteFile open(String filename) throws IOException {
|
||||
public RemoteFile open(String filename)
|
||||
throws IOException {
|
||||
return open(filename, EnumSet.of(OpenMode.READ));
|
||||
}
|
||||
|
||||
public RemoteDirectory openDir(String path) throws IOException {
|
||||
public RemoteDirectory openDir(String path)
|
||||
throws IOException {
|
||||
final String handle = doRequest(
|
||||
newRequest(PacketType.OPENDIR).putString(path)
|
||||
).ensurePacketTypeIs(PacketType.HANDLE).readString();
|
||||
return new RemoteDirectory(this, path, handle);
|
||||
}
|
||||
|
||||
public void setAttributes(String path, FileAttributes attrs) throws IOException {
|
||||
public void setAttributes(String path, FileAttributes attrs)
|
||||
throws IOException {
|
||||
doRequest(
|
||||
newRequest(PacketType.SETSTAT).putString(path).putFileAttributes(attrs)
|
||||
).ensureStatusPacketIsOK();
|
||||
}
|
||||
|
||||
public String readLink(String path) throws IOException {
|
||||
public String readLink(String path)
|
||||
throws IOException {
|
||||
return readSingleName(
|
||||
doRequest(
|
||||
newRequest(PacketType.READLINK).putString(path)
|
||||
));
|
||||
}
|
||||
|
||||
public void makeDir(String path, FileAttributes attrs) throws IOException {
|
||||
public void makeDir(String path, FileAttributes attrs)
|
||||
throws IOException {
|
||||
doRequest(
|
||||
newRequest(PacketType.MKDIR).putString(path).putFileAttributes(attrs)
|
||||
).ensureStatusPacketIsOK();
|
||||
}
|
||||
|
||||
public void makeDir(String path) throws IOException {
|
||||
public void makeDir(String path)
|
||||
throws IOException {
|
||||
makeDir(path, new FileAttributes());
|
||||
}
|
||||
|
||||
public void symlink(String linkpath, String targetpath) throws IOException {
|
||||
public void symlink(String linkpath, String targetpath)
|
||||
throws IOException {
|
||||
doRequest(
|
||||
newRequest(PacketType.SYMLINK).putString(linkpath).putString(targetpath)
|
||||
).ensureStatusPacketIsOK();
|
||||
}
|
||||
|
||||
public void remove(String filename) throws IOException {
|
||||
public void remove(String filename)
|
||||
throws IOException {
|
||||
doRequest(
|
||||
newRequest(PacketType.REMOVE).putString(filename)
|
||||
).ensureStatusPacketIsOK();
|
||||
}
|
||||
|
||||
public void removeDir(String path) throws IOException {
|
||||
public void removeDir(String path)
|
||||
throws IOException {
|
||||
doRequest(
|
||||
newRequest(PacketType.RMDIR).putString(path)
|
||||
).ensureStatusIs(Response.StatusCode.OK);
|
||||
}
|
||||
|
||||
private FileAttributes stat(PacketType pt, String path) throws IOException {
|
||||
private FileAttributes stat(PacketType pt, String path)
|
||||
throws IOException {
|
||||
return doRequest(newRequest(pt).putString(path))
|
||||
.ensurePacketTypeIs(PacketType.ATTRS)
|
||||
.readFileAttributes();
|
||||
}
|
||||
|
||||
public FileAttributes stat(String path) throws IOException {
|
||||
public FileAttributes stat(String path)
|
||||
throws IOException {
|
||||
return stat(PacketType.STAT, path);
|
||||
}
|
||||
|
||||
public FileAttributes lstat(String path) throws IOException {
|
||||
public FileAttributes lstat(String path)
|
||||
throws IOException {
|
||||
return stat(PacketType.LSTAT, path);
|
||||
}
|
||||
|
||||
public void rename(String oldPath, String newPath) throws IOException {
|
||||
public void rename(String oldPath, String newPath)
|
||||
throws IOException {
|
||||
doRequest(
|
||||
newRequest(PacketType.RENAME).putString(oldPath).putString(newPath)
|
||||
).ensureStatusPacketIsOK();
|
||||
}
|
||||
|
||||
public String canonicalize(String path) throws IOException {
|
||||
public String canonicalize(String path)
|
||||
throws IOException {
|
||||
return readSingleName(
|
||||
doRequest(
|
||||
newRequest(PacketType.REALPATH).putString(path)
|
||||
));
|
||||
}
|
||||
|
||||
private static String readSingleName(Response res) throws IOException {
|
||||
private static String readSingleName(Response res)
|
||||
throws IOException {
|
||||
res.ensurePacketTypeIs(PacketType.NAME);
|
||||
if (res.readInt() == 1)
|
||||
return res.readString();
|
||||
|
||||
@@ -20,7 +20,8 @@ import net.schmizz.sshj.common.DisconnectReason;
|
||||
import net.schmizz.sshj.common.SSHException;
|
||||
import net.schmizz.sshj.sftp.Response.StatusCode;
|
||||
|
||||
public class SFTPException extends SSHException {
|
||||
public class SFTPException
|
||||
extends SSHException {
|
||||
|
||||
public static final ExceptionChainer<SFTPException> chainer = new ExceptionChainer<SFTPException>() {
|
||||
|
||||
|
||||
@@ -30,7 +30,9 @@ import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.EnumSet;
|
||||
|
||||
public class SFTPFileTransfer extends AbstractFileTransfer implements FileTransfer {
|
||||
public class SFTPFileTransfer
|
||||
extends AbstractFileTransfer
|
||||
implements FileTransfer {
|
||||
|
||||
private final SFTPEngine sftp;
|
||||
private final PathHelper pathHelper;
|
||||
@@ -55,11 +57,13 @@ public class SFTPFileTransfer extends AbstractFileTransfer implements FileTransf
|
||||
this.pathHelper = new PathHelper(sftp);
|
||||
}
|
||||
|
||||
public void upload(String source, String dest) throws IOException {
|
||||
public void upload(String source, String dest)
|
||||
throws IOException {
|
||||
new Uploader(getModeGetter(), getUploadFilter()).upload(new File(source), dest);
|
||||
}
|
||||
|
||||
public void download(String source, String dest) throws IOException {
|
||||
public void download(String source, String dest)
|
||||
throws IOException {
|
||||
PathComponents src = pathHelper.getComponents(source);
|
||||
new Downloader(getModeSetter(), getDownloadFilter()).download(new RemoteResourceInfo(src.getParent(), src
|
||||
.getName(), sftp.stat(source)), new File(dest));
|
||||
@@ -91,7 +95,8 @@ public class SFTPFileTransfer extends AbstractFileTransfer implements FileTransf
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
private void setAttributes(RemoteResourceInfo remote, File local) throws IOException {
|
||||
private void setAttributes(RemoteResourceInfo remote, File local)
|
||||
throws IOException {
|
||||
final FileAttributes attrs = remote.getAttributes();
|
||||
modeSetter.setPermissions(local, attrs.getMode().getPermissionsMask());
|
||||
if (modeSetter.preservesTimes() && attrs.has(FileAttributes.Flag.ACMODTIME)) {
|
||||
@@ -100,7 +105,8 @@ public class SFTPFileTransfer extends AbstractFileTransfer implements FileTransf
|
||||
}
|
||||
}
|
||||
|
||||
private void downloadFile(RemoteResourceInfo remote, File local) throws IOException {
|
||||
private void downloadFile(RemoteResourceInfo remote, File local)
|
||||
throws IOException {
|
||||
local = FileTransferUtil.getTargetFile(local, remote.getName());
|
||||
setAttributes(remote, local);
|
||||
RemoteFile rf = sftp.open(remote.getPath());
|
||||
@@ -117,7 +123,8 @@ public class SFTPFileTransfer extends AbstractFileTransfer implements FileTransf
|
||||
}
|
||||
}
|
||||
|
||||
private void downloadDir(RemoteResourceInfo remote, File local) throws IOException {
|
||||
private void downloadDir(RemoteResourceInfo remote, File local)
|
||||
throws IOException {
|
||||
local = FileTransferUtil.getTargetDirectory(local, remote.getName());
|
||||
setAttributes(remote, local);
|
||||
final RemoteDirectory rd = sftp.openDir(remote.getPath());
|
||||
@@ -126,7 +133,8 @@ public class SFTPFileTransfer extends AbstractFileTransfer implements FileTransf
|
||||
rd.close();
|
||||
}
|
||||
|
||||
void download(RemoteResourceInfo remote, File local) throws IOException {
|
||||
void download(RemoteResourceInfo remote, File local)
|
||||
throws IOException {
|
||||
log.info("Downloading [{}] to [{}]", remote, local);
|
||||
if (remote.isDirectory())
|
||||
downloadDir(remote, local);
|
||||
@@ -147,7 +155,8 @@ public class SFTPFileTransfer extends AbstractFileTransfer implements FileTransf
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
public FileAttributes getAttributes(File local) throws IOException {
|
||||
public FileAttributes getAttributes(File local)
|
||||
throws IOException {
|
||||
FileAttributes.Builder builder = new FileAttributes.Builder().withPermissions(modeGetter
|
||||
.getPermissions(local));
|
||||
if (modeGetter.preservesTimes())
|
||||
@@ -156,17 +165,19 @@ public class SFTPFileTransfer extends AbstractFileTransfer implements FileTransf
|
||||
}
|
||||
|
||||
// tread carefully
|
||||
private void setAttributes(FileAttributes current, File local, String remote) throws IOException {
|
||||
private void setAttributes(FileAttributes current, File local, String remote)
|
||||
throws IOException {
|
||||
final FileAttributes attrs = getAttributes(local);
|
||||
// TODO whoaaa.. simplify?
|
||||
if (!(current != null
|
||||
&& current.getMode().getPermissionsMask() == attrs.getMode().getPermissionsMask()
|
||||
&& (!modeGetter.preservesTimes() || (attrs.getAtime() == current.getAtime() && attrs.getMtime() == current
|
||||
.getMtime()))))
|
||||
&& current.getMode().getPermissionsMask() == attrs.getMode().getPermissionsMask()
|
||||
&& (!modeGetter.preservesTimes()
|
||||
|| (attrs.getAtime() == current.getAtime() && attrs.getMtime() == current.getMtime()))))
|
||||
sftp.setAttributes(remote, attrs);
|
||||
}
|
||||
|
||||
private String prepareDir(File local, String remote) throws IOException {
|
||||
private String prepareDir(File local, String remote)
|
||||
throws IOException {
|
||||
FileAttributes attrs;
|
||||
try {
|
||||
attrs = sftp.stat(remote);
|
||||
@@ -192,7 +203,8 @@ public class SFTPFileTransfer extends AbstractFileTransfer implements FileTransf
|
||||
throw new IOException(attrs.getMode().getType() + " file already exists at " + remote);
|
||||
}
|
||||
|
||||
private String prepareFile(File local, String remote) throws IOException {
|
||||
private String prepareFile(File local, String remote)
|
||||
throws IOException {
|
||||
FileAttributes attrs;
|
||||
try {
|
||||
attrs = sftp.stat(remote);
|
||||
@@ -213,22 +225,24 @@ public class SFTPFileTransfer extends AbstractFileTransfer implements FileTransf
|
||||
}
|
||||
}
|
||||
|
||||
private void uploadDir(File local, String remote) throws IOException {
|
||||
private void uploadDir(File local, String remote)
|
||||
throws IOException {
|
||||
final String adjusted = prepareDir(local, remote);
|
||||
for (File f : local.listFiles(filter))
|
||||
upload(f, adjusted);
|
||||
}
|
||||
|
||||
private void uploadFile(File local, String remote) throws IOException {
|
||||
private void uploadFile(File local, String remote)
|
||||
throws IOException {
|
||||
final String adjusted = prepareFile(local, remote);
|
||||
final RemoteFile rf = sftp.open(adjusted, EnumSet.of(OpenMode.WRITE, OpenMode.CREAT, OpenMode.TRUNC),
|
||||
getAttributes(local));
|
||||
getAttributes(local));
|
||||
try {
|
||||
final FileInputStream fis = new FileInputStream(local);
|
||||
try {
|
||||
StreamCopier.copy(fis, //
|
||||
rf.getOutputStream(), sftp.getSubsystem().getRemoteMaxPacketSize()
|
||||
- rf.getOutgoingPacketOverhead(), false);
|
||||
rf.getOutputStream(), sftp.getSubsystem().getRemoteMaxPacketSize()
|
||||
- rf.getOutgoingPacketOverhead(), false);
|
||||
} finally {
|
||||
fis.close();
|
||||
}
|
||||
@@ -237,7 +251,8 @@ public class SFTPFileTransfer extends AbstractFileTransfer implements FileTransf
|
||||
}
|
||||
}
|
||||
|
||||
void upload(File local, String remote) throws IOException {
|
||||
void upload(File local, String remote)
|
||||
throws IOException {
|
||||
log.info("Uploading [{}] to [{}]", local, remote);
|
||||
if (local.isDirectory())
|
||||
uploadDir(local, remote);
|
||||
|
||||
@@ -17,7 +17,8 @@ package net.schmizz.sshj.sftp;
|
||||
|
||||
import net.schmizz.sshj.common.Buffer;
|
||||
|
||||
public class SFTPPacket<T extends SFTPPacket<T>> extends Buffer<T> {
|
||||
public class SFTPPacket<T extends SFTPPacket<T>>
|
||||
extends Buffer<T> {
|
||||
|
||||
public SFTPPacket() {
|
||||
super();
|
||||
|
||||
@@ -21,11 +21,13 @@ import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class StatefulSFTPClient extends SFTPClient {
|
||||
public class StatefulSFTPClient
|
||||
extends SFTPClient {
|
||||
|
||||
private String cwd;
|
||||
|
||||
public StatefulSFTPClient(SessionFactory ssh) throws IOException {
|
||||
public StatefulSFTPClient(SessionFactory ssh)
|
||||
throws IOException {
|
||||
super(ssh);
|
||||
this.cwd = getSFTPEngine().canonicalize(".");
|
||||
log.info("Start dir = " + cwd);
|
||||
@@ -40,25 +42,30 @@ public class StatefulSFTPClient extends SFTPClient {
|
||||
log.info("CWD = " + cwd);
|
||||
}
|
||||
|
||||
public synchronized List<RemoteResourceInfo> ls() throws IOException {
|
||||
public synchronized List<RemoteResourceInfo> ls()
|
||||
throws IOException {
|
||||
return ls(cwd, null);
|
||||
}
|
||||
|
||||
public synchronized List<RemoteResourceInfo> ls(RemoteResourceFilter filter) throws IOException {
|
||||
public synchronized List<RemoteResourceInfo> ls(RemoteResourceFilter filter)
|
||||
throws IOException {
|
||||
return ls(cwd, filter);
|
||||
}
|
||||
|
||||
public synchronized String pwd() throws IOException {
|
||||
public synchronized String pwd()
|
||||
throws IOException {
|
||||
return super.canonicalize(cwd);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RemoteResourceInfo> ls(String path) throws IOException {
|
||||
public List<RemoteResourceInfo> ls(String path)
|
||||
throws IOException {
|
||||
return ls(path, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RemoteResourceInfo> ls(String path, RemoteResourceFilter filter) throws IOException {
|
||||
public List<RemoteResourceInfo> ls(String path, RemoteResourceFilter filter)
|
||||
throws IOException {
|
||||
final RemoteDirectory dir = getSFTPEngine().openDir(cwdify(path));
|
||||
try {
|
||||
return dir.scan(filter);
|
||||
@@ -68,82 +75,98 @@ public class StatefulSFTPClient extends SFTPClient {
|
||||
}
|
||||
|
||||
@Override
|
||||
public RemoteFile open(String filename, Set<OpenMode> mode, FileAttributes attrs) throws IOException {
|
||||
public RemoteFile open(String filename, Set<OpenMode> mode, FileAttributes attrs)
|
||||
throws IOException {
|
||||
return super.open(cwdify(filename), mode, attrs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RemoteFile open(String filename, Set<OpenMode> mode) throws IOException {
|
||||
public RemoteFile open(String filename, Set<OpenMode> mode)
|
||||
throws IOException {
|
||||
return super.open(cwdify(filename), mode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RemoteFile open(String filename) throws IOException {
|
||||
public RemoteFile open(String filename)
|
||||
throws IOException {
|
||||
return super.open(cwdify(filename));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mkdir(String dirname) throws IOException {
|
||||
public void mkdir(String dirname)
|
||||
throws IOException {
|
||||
super.mkdir(cwdify(dirname));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rename(String oldpath, String newpath) throws IOException {
|
||||
public void rename(String oldpath, String newpath)
|
||||
throws IOException {
|
||||
super.rename(cwdify(oldpath), cwdify(newpath));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rm(String filename) throws IOException {
|
||||
public void rm(String filename)
|
||||
throws IOException {
|
||||
super.rm(cwdify(filename));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rmdir(String dirname) throws IOException {
|
||||
public void rmdir(String dirname)
|
||||
throws IOException {
|
||||
super.rmdir(cwdify(dirname));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void symlink(String linkpath, String targetpath) throws IOException {
|
||||
public void symlink(String linkpath, String targetpath)
|
||||
throws IOException {
|
||||
super.symlink(cwdify(linkpath), cwdify(targetpath));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setattr(String path, FileAttributes attrs) throws IOException {
|
||||
public void setattr(String path, FileAttributes attrs)
|
||||
throws IOException {
|
||||
super.setattr(cwdify(path), attrs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String readlink(String path) throws IOException {
|
||||
public String readlink(String path)
|
||||
throws IOException {
|
||||
return super.readlink(cwdify(path));
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileAttributes stat(String path) throws IOException {
|
||||
public FileAttributes stat(String path)
|
||||
throws IOException {
|
||||
return super.stat(cwdify(path));
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileAttributes lstat(String path) throws IOException {
|
||||
public FileAttributes lstat(String path)
|
||||
throws IOException {
|
||||
return super.lstat(cwdify(path));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void truncate(String path, long size) throws IOException {
|
||||
public void truncate(String path, long size)
|
||||
throws IOException {
|
||||
super.truncate(cwdify(path), size);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String canonicalize(String path) throws IOException {
|
||||
public String canonicalize(String path)
|
||||
throws IOException {
|
||||
return super.canonicalize(cwdify(path));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void get(String source, String dest) throws IOException {
|
||||
public void get(String source, String dest)
|
||||
throws IOException {
|
||||
super.get(cwdify(source), dest);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put(String source, String dest) throws IOException {
|
||||
public void put(String source, String dest)
|
||||
throws IOException {
|
||||
super.get(source, cwdify(dest));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user