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