You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by gn...@apache.org on 2015/07/17 18:18:42 UTC
[22/25] mina-sshd git commit: [SSHD-542] Checkstyle validation
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/17f2d627/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/AbstractSftpClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/AbstractSftpClient.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/AbstractSftpClient.java
index 8f92951..db7afc5 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/AbstractSftpClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/AbstractSftpClient.java
@@ -19,6 +19,34 @@
package org.apache.sshd.client.subsystem.sftp;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.file.attribute.FileTime;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.apache.sshd.client.subsystem.sftp.extensions.BuiltinSftpClientExtensions;
+import org.apache.sshd.client.subsystem.sftp.extensions.SftpClientExtension;
+import org.apache.sshd.client.subsystem.sftp.extensions.SftpClientExtensionFactory;
+import org.apache.sshd.common.SshException;
+import org.apache.sshd.common.subsystem.sftp.SftpConstants;
+import org.apache.sshd.common.subsystem.sftp.extensions.ParserUtils;
+import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.ValidateUtils;
+import org.apache.sshd.common.util.buffer.Buffer;
+import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
+import org.apache.sshd.common.util.io.InputStreamWithChannel;
+import org.apache.sshd.common.util.io.OutputStreamWithChannel;
+import org.apache.sshd.common.util.logging.AbstractLoggingBean;
+
import static org.apache.sshd.common.subsystem.sftp.SftpConstants.ACE4_APPEND_DATA;
import static org.apache.sshd.common.subsystem.sftp.SftpConstants.ACE4_READ_ATTRIBUTES;
import static org.apache.sshd.common.subsystem.sftp.SftpConstants.ACE4_READ_DATA;
@@ -86,44 +114,17 @@ import static org.apache.sshd.common.subsystem.sftp.SftpConstants.S_IFDIR;
import static org.apache.sshd.common.subsystem.sftp.SftpConstants.S_IFLNK;
import static org.apache.sshd.common.subsystem.sftp.SftpConstants.S_IFREG;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.nio.file.attribute.FileTime;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicReference;
-
-import org.apache.sshd.client.subsystem.sftp.extensions.BuiltinSftpClientExtensions;
-import org.apache.sshd.client.subsystem.sftp.extensions.SftpClientExtension;
-import org.apache.sshd.client.subsystem.sftp.extensions.SftpClientExtensionFactory;
-import org.apache.sshd.common.SshException;
-import org.apache.sshd.common.subsystem.sftp.SftpConstants;
-import org.apache.sshd.common.subsystem.sftp.extensions.ParserUtils;
-import org.apache.sshd.common.util.GenericUtils;
-import org.apache.sshd.common.util.ValidateUtils;
-import org.apache.sshd.common.util.buffer.Buffer;
-import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
-import org.apache.sshd.common.util.io.InputStreamWithChannel;
-import org.apache.sshd.common.util.io.OutputStreamWithChannel;
-import org.apache.sshd.common.util.logging.AbstractLoggingBean;
-
/**
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
public abstract class AbstractSftpClient extends AbstractLoggingBean implements SftpClient, RawSftpClient {
- private final AtomicReference<Map<String,Object>> parsedExtensionsHolder = new AtomicReference<Map<String,Object>>(null);
+
+ private final AtomicReference<Map<String, Object>> parsedExtensionsHolder = new AtomicReference<>(null);
protected AbstractSftpClient() {
super();
}
-
+
@Override
public String getName() {
return SftpConstants.SFTP_SUBSYSTEM_NAME;
@@ -133,9 +134,9 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
public CloseableHandle open(String path) throws IOException {
return open(path, Collections.<OpenMode>emptySet());
}
-
+
@Override
- public CloseableHandle open(String path, OpenMode ... options) throws IOException {
+ public CloseableHandle open(String path, OpenMode... options) throws IOException {
return open(path, GenericUtils.of(options));
}
@@ -143,9 +144,9 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
public void rename(String oldPath, String newPath) throws IOException {
rename(oldPath, newPath, Collections.<CopyMode>emptySet());
}
-
+
@Override
- public void rename(String oldPath, String newPath, CopyMode ... options) throws IOException {
+ public void rename(String oldPath, String newPath, CopyMode... options) throws IOException {
rename(oldPath, newPath, GenericUtils.of(options));
}
@@ -160,17 +161,17 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
}
@Override
- public InputStream read(String path, OpenMode ... mode) throws IOException {
+ public InputStream read(String path, OpenMode... mode) throws IOException {
return read(path, DEFAULT_READ_BUFFER_SIZE, mode);
}
@Override
- public InputStream read(String path, int bufferSize, OpenMode ... mode) throws IOException {
+ public InputStream read(String path, int bufferSize, OpenMode... mode) throws IOException {
return read(path, bufferSize, GenericUtils.of(mode));
}
@Override
- public InputStream read(String path, Collection<OpenMode> mode) throws IOException {
+ public InputStream read(String path, Collection<OpenMode> mode) throws IOException {
return read(path, DEFAULT_READ_BUFFER_SIZE, mode);
}
@@ -190,7 +191,7 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
}
@Override
- public OutputStream write(String path, OpenMode ... mode) throws IOException {
+ public OutputStream write(String path, OpenMode... mode) throws IOException {
return write(path, DEFAULT_WRITE_BUFFER_SIZE, mode);
}
@@ -200,7 +201,7 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
}
@Override
- public OutputStream write(String path, int bufferSize, OpenMode ... mode) throws IOException {
+ public OutputStream write(String path, int bufferSize, OpenMode... mode) throws IOException {
return write(path, bufferSize, GenericUtils.of(mode));
}
@@ -216,7 +217,7 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
@Override
public <E extends SftpClientExtension> E getExtension(Class<? extends E> extensionType) {
- Object instance = getExtension(BuiltinSftpClientExtensions.fromType(extensionType));
+ Object instance = getExtension(BuiltinSftpClientExtensions.fromType(extensionType));
if (instance == null) {
return null;
} else {
@@ -228,30 +229,31 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
public SftpClientExtension getExtension(String extensionName) {
return getExtension(BuiltinSftpClientExtensions.fromName(extensionName));
}
-
+
protected SftpClientExtension getExtension(SftpClientExtensionFactory factory) {
if (factory == null) {
return null;
}
- Map<String,byte[]> extensions = getServerExtensions();
- Map<String,Object> parsed = getParsedServerExtensions(extensions);
+ Map<String, byte[]> extensions = getServerExtensions();
+ Map<String, Object> parsed = getParsedServerExtensions(extensions);
return factory.create(this, this, extensions, parsed);
}
- protected Map<String,Object> getParsedServerExtensions() {
+ protected Map<String, Object> getParsedServerExtensions() {
return getParsedServerExtensions(getServerExtensions());
}
- protected Map<String,Object> getParsedServerExtensions(Map<String,byte[]> extensions) {
- Map<String,Object> parsed = parsedExtensionsHolder.get();
+ protected Map<String, Object> getParsedServerExtensions(Map<String, byte[]> extensions) {
+ Map<String, Object> parsed = parsedExtensionsHolder.get();
if (parsed == null) {
- if ((parsed=ParserUtils.parse(extensions)) == null) {
- parsed = Collections.<String,Object>emptyMap();
+ parsed = ParserUtils.parse(extensions);
+ if (parsed == null) {
+ parsed = Collections.emptyMap();
}
parsedExtensionsHolder.set(parsed);
}
-
+
return parsed;
}
@@ -302,7 +304,7 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
*/
protected void checkStatus(int id, int substatus, String msg, String lang) throws IOException {
if (log.isTraceEnabled()) {
- log.trace("checkStatus(id=" + id + ") status: " + substatus + " [" + lang + "]" + msg );
+ log.trace("checkStatus(id=" + id + ") status: " + substatus + " [" + lang + "]" + msg);
}
if (substatus != SSH_FX_OK) {
@@ -410,7 +412,8 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
if (len != 1) {
throw new SshException("SFTP error: received " + len + " names instead of 1");
}
- String name = buffer.getString(), longName = null;
+ String name = buffer.getString();
+ String longName = null;
int version = getVersion();
if (version == SFTP_V3) {
longName = buffer.getString();
@@ -474,7 +477,7 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
attrs.flags.add(Attribute.Perms);
attrs.perms = buffer.getInt();
}
-
+
// update the permissions according to the type
switch (attrs.type) {
case SSH_FILEXFER_TYPE_REGULAR:
@@ -515,7 +518,7 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
long secs = buffer.getLong();
long millis = secs * 1000;
if ((flags & SSH_FILEXFER_ATTR_SUBSECOND_TIMES) != 0) {
- millis += buffer.getInt() / 1000000l;
+ millis += buffer.getInt() / 1000000L;
}
return FileTime.from(millis, TimeUnit.MILLISECONDS);
}
@@ -641,7 +644,8 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
Buffer buffer = new ByteArrayBuffer(path.length() + Long.SIZE /* some extra fields */);
buffer.putString(path);
- int version = getVersion(), mode = 0;
+ int version = getVersion();
+ int mode = 0;
if (version == SFTP_V3) {
for (OpenMode m : options) {
switch (m) {
@@ -730,7 +734,7 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
Buffer buffer = new ByteArrayBuffer(oldPath.length() + newPath.length() + Long.SIZE /* some extra fields */);
buffer.putString(oldPath);
buffer.putString(newPath);
-
+
int numOptions = GenericUtils.size(options);
int version = getVersion();
if (version >= SFTP_V5) {
@@ -751,7 +755,7 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
buffer.putInt(opts);
} else if (numOptions > 0) {
throw new UnsupportedOperationException("rename(" + oldPath + " => " + newPath + ")"
- + " - copy options can not be used with this SFTP version: " + options);
+ + " - copy options can not be used with this SFTP version: " + options);
}
checkStatus(SSH_FXP_RENAME, buffer);
}
@@ -809,13 +813,13 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
// do some bounds checking first
if ((fileOffset < 0) || (srcOffset < 0) || (len < 0)) {
throw new IllegalArgumentException("write(" + handle + ") please ensure all parameters "
- + " are non-negative values: file-offset=" + fileOffset
- + ", src-offset=" + srcOffset + ", len=" + len);
+ + " are non-negative values: file-offset=" + fileOffset
+ + ", src-offset=" + srcOffset + ", len=" + len);
}
if ((srcOffset + len) > src.length) {
throw new IllegalArgumentException("write(" + handle + ")"
- + " cannot read bytes " + srcOffset + " to " + (srcOffset + len)
- + " when array is only of length " + src.length);
+ + " cannot read bytes " + srcOffset + " to " + (srcOffset + len)
+ + " when array is only of length " + src.length);
}
if (!isOpen()) {
throw new IOException("write(" + handle + "/" + fileOffset + ")[" + srcOffset + "/" + len + "] client is closed");
@@ -835,7 +839,7 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
throw new IOException("mkdir(" + path + ") client is closed");
}
- Buffer buffer = new ByteArrayBuffer(path.length() + Long.SIZE /* some extra fields */);
+ Buffer buffer = new ByteArrayBuffer(path.length() + Long.SIZE /* some extra fields */);
buffer.putString(path);
buffer.putInt(0);
@@ -853,7 +857,7 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
throw new IOException("rmdir(" + path + ") client is closed");
}
- Buffer buffer = new ByteArrayBuffer(path.length() + Long.SIZE /* some extra fields */);
+ Buffer buffer = new ByteArrayBuffer(path.length() + Long.SIZE /* some extra fields */);
buffer.putString(path);
checkStatus(SSH_FXP_RMDIR, buffer);
}
@@ -1076,79 +1080,7 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
if (!isOpen()) {
throw new IOException("readDir(" + path + ") client is closed");
}
-
- return new Iterable<DirEntry>() {
- @Override
- public Iterator<DirEntry> iterator() {
- return new Iterator<DirEntry>() {
- private CloseableHandle handle;
- private List<DirEntry> entries;
- private int index;
-
- {
- open();
- load();
- }
-
- @Override
- public boolean hasNext() {
- return (entries != null) && (index < entries.size());
- }
-
- @Override
- public DirEntry next() {
- DirEntry entry = entries.get(index++);
- if (index >= entries.size()) {
- load();
- }
- return entry;
- }
-
- @SuppressWarnings("synthetic-access")
- private void open() {
- try {
- handle = openDir(path);
- if (log.isDebugEnabled()) {
- log.debug("readDir(" + path + ") handle=" + handle);
- }
- } catch (IOException e) {
- if (log.isDebugEnabled()) {
- log.debug("readDir(" + path + ") failed (" + e.getClass().getSimpleName() + ") to open dir: " + e.getMessage());
- }
- throw new RuntimeException(e);
- }
- }
-
- @SuppressWarnings("synthetic-access")
- private void load() {
- try {
- entries = readDir(handle);
- index = 0;
- if (entries == null) {
- handle.close();
- }
- } catch (IOException e) {
- entries = null;
- try {
- handle.close();
- } catch (IOException t) {
- if (log.isTraceEnabled()) {
- log.trace(t.getClass().getSimpleName() + " while close handle=" + handle
- + " due to " + e.getClass().getSimpleName() + " [" + e.getMessage() + "]"
- + ": " + t.getMessage());
- }
- }
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public void remove() {
- throw new UnsupportedOperationException("readDir(" + path + ") Iterator#remove() N/A");
- }
- };
- }
- };
+ return new DirEntryIterable(path);
}
@Override
@@ -1161,147 +1093,249 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
throw new IOException("read(" + path + ")[" + mode + "] size=" + bufferSize + ": client is closed");
}
- return new InputStreamWithChannel() {
- private byte[] bb = new byte[1];
- private byte[] buffer = new byte[bufferSize];
+ return new SftpInputStreamWithChannel(bufferSize, path, mode);
+ }
+
+ @Override
+ public OutputStream write(final String path, final int bufferSize, final Collection<OpenMode> mode) throws IOException {
+ if (bufferSize < MIN_WRITE_BUFFER_SIZE) {
+ throw new IllegalArgumentException("Insufficient write buffer size: " + bufferSize + ", min.=" + MIN_WRITE_BUFFER_SIZE);
+ }
+
+ if (!isOpen()) {
+ throw new IOException("write(" + path + ")[" + mode + "] size=" + bufferSize + ": client is closed");
+ }
+
+ return new SftpOutputStreamWithChannel(bufferSize, path, mode);
+ }
+
+ private class DirEntryIterable implements Iterable<DirEntry> {
+
+ private final String path;
+
+ public DirEntryIterable(String path) {
+ this.path = path;
+ }
+
+ @Override
+ public Iterator<DirEntry> iterator() {
+ return new DirEntryIterator();
+ }
+
+ private class DirEntryIterator implements Iterator<DirEntry> {
+ private CloseableHandle handle;
+ private List<DirEntry> entries;
private int index;
- private int available;
- private CloseableHandle handle = AbstractSftpClient.this.open(path, mode);
- private long offset;
- @Override
- public boolean isOpen() {
- return (handle != null) && handle.isOpen();
+ public DirEntryIterator() {
+ open();
+ load();
}
@Override
- public int read() throws IOException {
- int read = read(bb, 0, 1);
- if (read > 0) {
- return bb[0];
- }
-
- return read;
+ public boolean hasNext() {
+ return (entries != null) && (index < entries.size());
}
@Override
- public int read(byte[] b, int off, int len) throws IOException {
- if (!isOpen()) {
- throw new IOException("read(" + path + ") stream closed");
+ public DirEntry next() {
+ DirEntry entry = entries.get(index++);
+ if (index >= entries.size()) {
+ load();
}
+ return entry;
+ }
- int idx = off;
- while (len > 0) {
- if (index >= available) {
- available = AbstractSftpClient.this.read(handle, offset, buffer, 0, buffer.length);
- if (available < 0) {
- if (idx == off) {
- return -1;
- } else {
- break;
- }
- }
- offset += available;
- index = 0;
+ @SuppressWarnings("synthetic-access")
+ private void open() {
+ try {
+ handle = openDir(path);
+ if (log.isDebugEnabled()) {
+ log.debug("readDir(" + path + ") handle=" + handle);
}
- if (index >= available) {
- break;
+ } catch (IOException e) {
+ if (log.isDebugEnabled()) {
+ log.debug("readDir(" + path + ") failed (" + e.getClass().getSimpleName() + ") to open dir: " + e.getMessage());
}
- int nb = Math.min(len, available - index);
- System.arraycopy(buffer, index, b, idx, nb);
- index += nb;
- idx += nb;
- len -= nb;
+ throw new RuntimeException(e);
}
- return idx - off;
}
- @Override
- public void close() throws IOException {
- if (isOpen()) {
+ @SuppressWarnings("synthetic-access")
+ private void load() {
+ try {
+ entries = readDir(handle);
+ index = 0;
+ if (entries == null) {
+ handle.close();
+ }
+ } catch (IOException e) {
+ entries = null;
try {
handle.close();
- } finally {
- handle = null;
+ } catch (IOException t) {
+ if (log.isTraceEnabled()) {
+ log.trace(t.getClass().getSimpleName() + " while close handle=" + handle
+ + " due to " + e.getClass().getSimpleName() + " [" + e.getMessage() + "]"
+ + ": " + t.getMessage());
+ }
}
+ throw new RuntimeException(e);
}
}
- };
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException("readDir(" + path + ") Iterator#remove() N/A");
+ }
+ }
}
- @Override
- public OutputStream write(final String path, final int bufferSize, final Collection<OpenMode> mode) throws IOException {
- if (bufferSize < MIN_WRITE_BUFFER_SIZE) {
- throw new IllegalArgumentException("Insufficient write buffer size: " + bufferSize + ", min.=" + MIN_WRITE_BUFFER_SIZE);
+ private class SftpOutputStreamWithChannel extends OutputStreamWithChannel {
+ private final String path;
+ private byte[] bb;
+ private byte[] buffer;
+ private int index;
+ private CloseableHandle handle;
+ private long offset;
+
+ public SftpOutputStreamWithChannel(int bufferSize, String path, Collection<OpenMode> mode) throws IOException {
+ this.path = path;
+ bb = new byte[1];
+ buffer = new byte[bufferSize];
+ handle = AbstractSftpClient.this.open(path, mode);
}
- if (!isOpen()) {
- throw new IOException("write(" + path + ")[" + mode + "] size=" + bufferSize + ": client is closed");
+ @Override
+ public boolean isOpen() {
+ return (handle != null) && handle.isOpen();
}
- return new OutputStreamWithChannel() {
- private byte[] bb = new byte[1];
- private byte[] buffer = new byte[bufferSize];
- private int index;
- private CloseableHandle handle = AbstractSftpClient.this.open(path, mode);
- private long offset;
+ @Override
+ public void write(int b) throws IOException {
+ bb[0] = (byte) b;
+ write(bb, 0, 1);
+ }
- @Override
- public boolean isOpen() {
- return (handle != null) && handle.isOpen();
+ @Override
+ public void write(byte[] b, int off, int len) throws IOException {
+ if (!isOpen()) {
+ throw new IOException("write(" + path + ")[len=" + len + "] stream is closed");
}
- @Override
- public void write(int b) throws IOException {
- bb[0] = (byte) b;
- write(bb, 0, 1);
+ do {
+ int nb = Math.min(len, buffer.length - index);
+ System.arraycopy(b, off, buffer, index, nb);
+ index += nb;
+ if (index == buffer.length) {
+ flush();
+ }
+ off += nb;
+ len -= nb;
+ } while (len > 0);
+ }
+
+ @Override
+ public void flush() throws IOException {
+ if (!isOpen()) {
+ throw new IOException("flush(" + path + ") stream is closed");
}
- @Override
- public void write(byte[] b, int off, int len) throws IOException {
- if (!isOpen()) {
- throw new IOException("write(" + path + ")[len=" + len + "] stream is closed");
- }
+ AbstractSftpClient.this.write(handle, offset, buffer, 0, index);
+ offset += index;
+ index = 0;
+ }
- do {
- int nb = Math.min(len, buffer.length - index);
- System.arraycopy(b, off, buffer, index, nb);
- index += nb;
- if (index == buffer.length) {
- flush();
+ @Override
+ public void close() throws IOException {
+ if (isOpen()) {
+ try {
+ try {
+ if (index > 0) {
+ flush();
+ }
+ } finally {
+ handle.close();
}
- off += nb;
- len -= nb;
- } while (len > 0);
+ } finally {
+ handle = null;
+ }
+ }
+ }
+ }
+
+ private class SftpInputStreamWithChannel extends InputStreamWithChannel {
+ private final String path;
+ private byte[] bb;
+ private byte[] buffer;
+ private int index;
+ private int available;
+ private CloseableHandle handle;
+ private long offset;
+
+ public SftpInputStreamWithChannel(int bufferSize, String path, Collection<OpenMode> mode) throws IOException {
+ this.path = path;
+ bb = new byte[1];
+ buffer = new byte[bufferSize];
+ handle = AbstractSftpClient.this.open(path, mode);
+ }
+
+ @Override
+ public boolean isOpen() {
+ return (handle != null) && handle.isOpen();
+ }
+
+ @Override
+ public int read() throws IOException {
+ int read = read(bb, 0, 1);
+ if (read > 0) {
+ return bb[0];
}
- @Override
- public void flush() throws IOException {
- if (!isOpen()) {
- throw new IOException("flush(" + path + ") stream is closed");
- }
+ return read;
+ }
- AbstractSftpClient.this.write(handle, offset, buffer, 0, index);
- offset += index;
- index = 0;
+ @Override
+ public int read(byte[] b, int off, int len) throws IOException {
+ if (!isOpen()) {
+ throw new IOException("read(" + path + ") stream closed");
}
- @Override
- public void close() throws IOException {
- if (isOpen()) {
- try {
- try {
- if (index > 0) {
- flush();
- }
- } finally {
- handle.close();
+ int idx = off;
+ while (len > 0) {
+ if (index >= available) {
+ available = AbstractSftpClient.this.read(handle, offset, buffer, 0, buffer.length);
+ if (available < 0) {
+ if (idx == off) {
+ return -1;
+ } else {
+ break;
}
- } finally {
- handle = null;
}
+ offset += available;
+ index = 0;
+ }
+ if (index >= available) {
+ break;
}
+ int nb = Math.min(len, available - index);
+ System.arraycopy(buffer, index, b, idx, nb);
+ index += nb;
+ idx += nb;
+ len -= nb;
}
- };
+ return idx - off;
+ }
+
+ @Override
+ public void close() throws IOException {
+ if (isOpen()) {
+ try {
+ handle.close();
+ } finally {
+ handle = null;
+ }
+ }
+ }
}
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/17f2d627/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/DefaultSftpClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/DefaultSftpClient.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/DefaultSftpClient.java
index dd313db..feb156a 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/DefaultSftpClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/DefaultSftpClient.java
@@ -18,12 +18,6 @@
*/
package org.apache.sshd.client.subsystem.sftp;
-import static org.apache.sshd.common.subsystem.sftp.SftpConstants.SFTP_V3;
-import static org.apache.sshd.common.subsystem.sftp.SftpConstants.SFTP_V6;
-import static org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXP_INIT;
-import static org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXP_STATUS;
-import static org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXP_VERSION;
-
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -52,6 +46,12 @@ import org.apache.sshd.common.util.buffer.Buffer;
import org.apache.sshd.common.util.buffer.BufferUtils;
import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
+import static org.apache.sshd.common.subsystem.sftp.SftpConstants.SFTP_V3;
+import static org.apache.sshd.common.subsystem.sftp.SftpConstants.SFTP_V6;
+import static org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXP_INIT;
+import static org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXP_STATUS;
+import static org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXP_VERSION;
+
/**
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
@@ -64,8 +64,8 @@ public class DefaultSftpClient extends AbstractSftpClient {
private final byte[] workBuf = new byte[Integer.SIZE / Byte.SIZE]; // TODO in JDK-8 use Integer.BYTES
private boolean closing;
private int version;
- private final Map<String,byte[]> extensions = new TreeMap<String,byte[]>(String.CASE_INSENSITIVE_ORDER);
- private final Map<String,byte[]> exposedExtensions = Collections.unmodifiableMap(extensions);
+ private final Map<String, byte[]> extensions = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
+ private final Map<String, byte[]> exposedExtensions = Collections.unmodifiableMap(extensions);
public DefaultSftpClient(ClientSession clientSession) throws IOException {
this.clientSession = ValidateUtils.checkNotNull(clientSession, "No client session", GenericUtils.EMPTY_OBJECT_ARRAY);
@@ -73,8 +73,9 @@ public class DefaultSftpClient extends AbstractSftpClient {
this.channel.setOut(new OutputStream() {
@Override
public void write(int b) throws IOException {
- write(new byte[] { (byte) b }, 0, 1);
+ write(new byte[]{(byte) b}, 0, 1);
}
+
@Override
public void write(byte[] b, int off, int len) throws IOException {
data(b, off, len);
@@ -131,7 +132,7 @@ public class DefaultSftpClient extends AbstractSftpClient {
* Receive binary data
*/
protected int data(byte[] buf, int start, int len) throws IOException {
- Buffer incoming = new ByteArrayBuffer(buf, start, len);
+ Buffer incoming = new ByteArrayBuffer(buf, start, len);
// If we already have partial data, we need to append it to the buffer and use it
if (receiveBuffer.available() > 0) {
receiveBuffer.putBuffer(incoming);
@@ -139,7 +140,7 @@ public class DefaultSftpClient extends AbstractSftpClient {
}
// Process commands
int rpos = incoming.rpos();
- for (int count=0; receive(incoming); count++) {
+ for (int count = 0; receive(incoming); count++) {
if (log.isTraceEnabled()) {
log.trace("Processed " + count + " data messages");
}
@@ -189,17 +190,18 @@ public class DefaultSftpClient extends AbstractSftpClient {
int id = buffer.getInt();
buffer.rpos(0);
synchronized (messages) {
- messages.put(Integer.valueOf(id), buffer);
+ messages.put(id, buffer);
messages.notifyAll();
}
}
@Override
public int send(int cmd, Buffer buffer) throws IOException {
- int id = cmdId.incrementAndGet(), len = buffer.available();
+ int id = cmdId.incrementAndGet();
+ int len = buffer.available();
if (log.isTraceEnabled()) {
log.trace("send(cmd={}, len={}) id = {}",
- Integer.valueOf(cmd), Integer.valueOf(len), Integer.valueOf(id));
+ cmd, len, id);
}
OutputStream dos = channel.getInvertedIn();
@@ -213,9 +215,9 @@ public class DefaultSftpClient extends AbstractSftpClient {
@Override
public Buffer receive(int id) throws IOException {
- Integer reqId = Integer.valueOf(id);
+ Integer reqId = id;
synchronized (messages) {
- for (int count=1; ; count++) {
+ for (int count = 1;; count++) {
if (closing) {
throw new SshException("Channel has been closed");
}
@@ -313,10 +315,10 @@ public class DefaultSftpClient extends AbstractSftpClient {
*/
public int negotiateVersion(SftpVersionSelector selector) throws IOException {
int current = getVersion();
- Set<Integer> available = GenericUtils.asSortedSet(Collections.singleton(Integer.valueOf(current)));
- Map<String,?> parsed = getParsedServerExtensions();
+ Set<Integer> available = GenericUtils.asSortedSet(Collections.singleton(current));
+ Map<String, ?> parsed = getParsedServerExtensions();
Collection<String> extensions = ParserUtils.supportedExtensions(parsed);
- if ((GenericUtils.size(extensions) > 0) && extensions.contains(SftpConstants.EXT_VERSELECT)) {
+ if ((GenericUtils.size(extensions) > 0) && extensions.contains(SftpConstants.EXT_VERSION_SELECT)) {
Versions vers = GenericUtils.isEmpty(parsed) ? null : (Versions) parsed.get(SftpConstants.EXT_VERSIONS);
Collection<String> reported = (vers == null) ? null : vers.versions;
if (GenericUtils.size(reported) > 0) {
@@ -328,9 +330,9 @@ public class DefaultSftpClient extends AbstractSftpClient {
}
}
- int selected = selector.selectVersion(current, new ArrayList<Integer>(available));
+ int selected = selector.selectVersion(current, new ArrayList<>(available));
if (log.isDebugEnabled()) {
- log.debug("negotiateVersion({}) {} -> {}", Integer.valueOf(current), available, Integer.valueOf(selected));
+ log.debug("negotiateVersion({}) {} -> {}", current, available, selected);
}
if (selected == current) {
@@ -342,9 +344,9 @@ public class DefaultSftpClient extends AbstractSftpClient {
}
String verVal = String.valueOf(selected);
- Buffer buffer = new ByteArrayBuffer((Integer.SIZE / Byte.SIZE) + SftpConstants.EXT_VERSELECT.length() // extension name
- + (Integer.SIZE / Byte.SIZE) + verVal.length());
- buffer.putString(SftpConstants.EXT_VERSELECT);
+ Buffer buffer = new ByteArrayBuffer((Integer.SIZE / Byte.SIZE) + SftpConstants.EXT_VERSION_SELECT.length() // extension name
+ + (Integer.SIZE / Byte.SIZE) + verVal.length());
+ buffer.putString(SftpConstants.EXT_VERSION_SELECT);
buffer.putString(verVal);
checkStatus(SftpConstants.SSH_FXP_EXTENDED, buffer);
version = selected;
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/17f2d627/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/RawSftpClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/RawSftpClient.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/RawSftpClient.java
index ab80812..bd283a9 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/RawSftpClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/RawSftpClient.java
@@ -28,13 +28,13 @@ import org.apache.sshd.common.util.buffer.Buffer;
*/
public interface RawSftpClient {
/**
- * @param cmd Command to send - <B>Note:</B> only lower 8-bits are used
+ * @param cmd Command to send - <B>Note:</B> only lower 8-bits are used
* @param buffer The {@link Buffer} containing the command data
* @return The assigned request id
* @throws IOException if failed to send command
*/
int send(int cmd, Buffer buffer) throws IOException;
-
+
/**
* @param id The expected request id
* @return The received response {@link Buffer} containing the request id
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/17f2d627/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpClient.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpClient.java
index 598a2fe..0c7032c 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpClient.java
@@ -18,11 +18,6 @@
*/
package org.apache.sshd.client.subsystem.sftp;
-import static org.apache.sshd.common.subsystem.sftp.SftpConstants.S_IFDIR;
-import static org.apache.sshd.common.subsystem.sftp.SftpConstants.S_IFLNK;
-import static org.apache.sshd.common.subsystem.sftp.SftpConstants.S_IFMT;
-import static org.apache.sshd.common.subsystem.sftp.SftpConstants.S_IFREG;
-
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
@@ -43,6 +38,11 @@ import org.apache.sshd.common.util.ValidateUtils;
import org.apache.sshd.common.util.buffer.BufferUtils;
import org.bouncycastle.util.Arrays;
+import static org.apache.sshd.common.subsystem.sftp.SftpConstants.S_IFDIR;
+import static org.apache.sshd.common.subsystem.sftp.SftpConstants.S_IFLNK;
+import static org.apache.sshd.common.subsystem.sftp.SftpConstants.S_IFMT;
+import static org.apache.sshd.common.subsystem.sftp.SftpConstants.S_IFREG;
+
/**
* @author <a href="http://mina.apache.org">Apache MINA Project</a>
*/
@@ -103,7 +103,7 @@ public interface SftpClient extends SubsystemClient {
if (obj == null) {
return false;
}
-
+
if (obj == this) {
return true;
}
@@ -112,12 +112,8 @@ public interface SftpClient extends SubsystemClient {
if (!(obj instanceof Handle)) {
return false;
}
-
- if (Arrays.areEqual(id, ((Handle) obj).id)) {
- return true;
- } else {
- return false;
- }
+
+ return Arrays.areEqual(id, ((Handle) obj).id);
}
@Override
@@ -133,6 +129,7 @@ public interface SftpClient extends SubsystemClient {
}
class Attributes {
+ // CHECKSTYLE:OFF
public final Set<Attribute> flags = EnumSet.noneOf(Attribute.class);
public long size;
public int type;
@@ -147,21 +144,21 @@ public interface SftpClient extends SubsystemClient {
public FileTime accessTime;
public FileTime createTime;
public FileTime modifyTime;
+ // CHECKSTYLE:ON
@Override
public String toString() {
return "type=" + type
- + ";size=" + size
- + ";uid=" + uid
- + ";gid=" + gid
- + ";perms=0x" + Integer.toHexString(perms)
- + ";flags=" + flags
- + ";owner=" + owner
- + ";group=" + group
- + ";aTime=(" + atime + ")[" + accessTime + "]"
- + ";cTime=(" + ctime + ")[" + createTime + "]"
- + ";mTime=(" + mtime + ")[" + modifyTime + "]"
- ;
+ + ";size=" + size
+ + ";uid=" + uid
+ + ";gid=" + gid
+ + ";perms=0x" + Integer.toHexString(perms)
+ + ";flags=" + flags
+ + ";owner=" + owner
+ + ";group=" + group
+ + ";aTime=(" + atime + ")[" + accessTime + "]"
+ + ";cTime=(" + ctime + ")[" + createTime + "]"
+ + ";mTime=(" + mtime + ")[" + modifyTime + "]";
}
public Attributes size(long size) {
@@ -169,6 +166,7 @@ public interface SftpClient extends SubsystemClient {
this.size = size;
return this;
}
+
public Attributes owner(String owner) {
flags.add(Attribute.OwnerGroup);
this.owner = owner;
@@ -177,6 +175,7 @@ public interface SftpClient extends SubsystemClient {
}
return this;
}
+
public Attributes group(String group) {
flags.add(Attribute.OwnerGroup);
this.group = group;
@@ -185,77 +184,93 @@ public interface SftpClient extends SubsystemClient {
}
return this;
}
+
public Attributes owner(int uid, int gid) {
flags.add(Attribute.UidGid);
this.uid = uid;
this.gid = gid;
return this;
}
+
public Attributes perms(int perms) {
flags.add(Attribute.Perms);
this.perms = perms;
return this;
}
+
public Attributes atime(int atime) {
flags.add(Attribute.AccessTime);
this.atime = atime;
this.accessTime = FileTime.from(atime, TimeUnit.SECONDS);
return this;
}
+
public Attributes ctime(int ctime) {
flags.add(Attribute.CreateTime);
this.ctime = ctime;
this.createTime = FileTime.from(atime, TimeUnit.SECONDS);
return this;
}
+
public Attributes mtime(int mtime) {
flags.add(Attribute.ModifyTime);
this.mtime = mtime;
this.modifyTime = FileTime.from(atime, TimeUnit.SECONDS);
return this;
}
+
public Attributes time(int atime, int mtime) {
flags.add(Attribute.AcModTime);
this.atime = atime;
this.mtime = mtime;
return this;
}
+
public Attributes accessTime(FileTime atime) {
flags.add(Attribute.AccessTime);
this.atime = (int) atime.to(TimeUnit.SECONDS);
this.accessTime = atime;
return this;
}
+
public Attributes createTime(FileTime ctime) {
flags.add(Attribute.CreateTime);
this.ctime = (int) ctime.to(TimeUnit.SECONDS);
this.createTime = ctime;
return this;
}
+
public Attributes modifyTime(FileTime mtime) {
flags.add(Attribute.ModifyTime);
this.mtime = (int) mtime.to(TimeUnit.SECONDS);
this.modifyTime = mtime;
return this;
}
+
public boolean isRegularFile() {
return (perms & S_IFMT) == S_IFREG;
}
+
public boolean isDirectory() {
return (perms & S_IFMT) == S_IFDIR;
}
+
public boolean isSymbolicLink() {
return (perms & S_IFMT) == S_IFLNK;
}
+
public boolean isOther() {
return !isRegularFile() && !isDirectory() && !isSymbolicLink();
}
}
class DirEntry {
+ // CHECKSTYLE:OFF
public String filename;
public String longFilename;
public Attributes attributes;
+ // CHECKSTYLE:ON
+
public DirEntry(String filename, String longFilename, Attributes attributes) {
this.filename = filename;
this.longFilename = longFilename;
@@ -263,12 +278,30 @@ public interface SftpClient extends SubsystemClient {
}
}
+ // default values used if none specified
+ int MIN_BUFFER_SIZE = Byte.MAX_VALUE;
+ int MIN_READ_BUFFER_SIZE = MIN_BUFFER_SIZE;
+ int MIN_WRITE_BUFFER_SIZE = MIN_BUFFER_SIZE;
+ int IO_BUFFER_SIZE = 32 * 1024;
+ int DEFAULT_READ_BUFFER_SIZE = IO_BUFFER_SIZE;
+ int DEFAULT_WRITE_BUFFER_SIZE = IO_BUFFER_SIZE;
+ long DEFAULT_WAIT_TIMEOUT = TimeUnit.SECONDS.toMillis(30L);
+
+ /**
+ * Property that can be used on the {@link org.apache.sshd.common.FactoryManager}
+ * to control the internal timeout used by the client to open a channel.
+ * If not specified then {@link #DEFAULT_CHANNEL_OPEN_TIMEOUT} value
+ * is used
+ */
+ String SFTP_CHANNEL_OPEN_TIMEOUT = "sftp-channel-open-timeout";
+ long DEFAULT_CHANNEL_OPEN_TIMEOUT = DEFAULT_WAIT_TIMEOUT;
+
int getVersion();
/**
* @return An (unmodifiable) {@link Map} of the reported server extensions.
*/
- Map<String,byte[]> getServerExtensions();
+ Map<String, byte[]> getServerExtensions();
boolean isClosing();
@@ -278,6 +311,7 @@ public interface SftpClient extends SubsystemClient {
/**
* Opens a remote file for read
+ *
* @param path The remote path
* @return The file's {@link CloseableHandle}
* @throws IOException If failed to open the remote file
@@ -286,19 +320,21 @@ public interface SftpClient extends SubsystemClient {
/**
* Opens a remote file with the specified mode(s)
- * @param path The remote path
+ *
+ * @param path The remote path
* @param options The desired mode - if none specified
- * then {@link OpenMode#Read} is assumed
+ * then {@link OpenMode#Read} is assumed
* @return The file's {@link CloseableHandle}
* @throws IOException If failed to open the remote file
*/
- CloseableHandle open(String path, OpenMode ... options) throws IOException;
+ CloseableHandle open(String path, OpenMode... options) throws IOException;
/**
* Opens a remote file with the specified mode(s)
- * @param path The remote path
+ *
+ * @param path The remote path
* @param options The desired mode - if none specified
- * then {@link OpenMode#Read} is assumed
+ * then {@link OpenMode#Read} is assumed
* @return The file's {@link CloseableHandle}
* @throws IOException If failed to open the remote file
*/
@@ -309,13 +345,17 @@ public interface SftpClient extends SubsystemClient {
void remove(String path) throws IOException;
void rename(String oldPath, String newPath) throws IOException;
+
void rename(String oldPath, String newPath, CopyMode... options) throws IOException;
+
void rename(String oldPath, String newPath, Collection<CopyMode> options) throws IOException;
int read(Handle handle, long fileOffset, byte[] dst) throws IOException;
+
int read(Handle handle, long fileOffset, byte[] dst, int dstOffset, int len) throws IOException;
void write(Handle handle, long fileOffset, byte[] src) throws IOException;
+
void write(Handle handle, long fileOffset, byte[] src, int srcOffset, int len) throws IOException;
void mkdir(String path) throws IOException;
@@ -371,32 +411,28 @@ public interface SftpClient extends SubsystemClient {
*/
Iterable<DirEntry> readDir(String path) throws IOException;
- // default values used if none specified
- int MIN_BUFFER_SIZE=Byte.MAX_VALUE, MIN_READ_BUFFER_SIZE=MIN_BUFFER_SIZE, MIN_WRITE_BUFFER_SIZE=MIN_BUFFER_SIZE;
- int IO_BUFFER_SIZE=32 * 1024, DEFAULT_READ_BUFFER_SIZE=IO_BUFFER_SIZE, DEFAULT_WRITE_BUFFER_SIZE=IO_BUFFER_SIZE;
- long DEFAULT_WAIT_TIMEOUT=TimeUnit.SECONDS.toMillis(30L);
-
- /**
- * Property that can be used on the {@link org.apache.sshd.common.FactoryManager}
- * to control the internal timeout used by the client to open a channel.
- * If not specified then {@link #DEFAULT_CHANNEL_OPEN_TIMEOUT} value
- * is used
- */
- String SFTP_CHANNEL_OPEN_TIMEOUT = "sftp-channel-open-timeout";
- long DEFAULT_CHANNEL_OPEN_TIMEOUT = DEFAULT_WAIT_TIMEOUT;
-
InputStream read(String path) throws IOException;
+
InputStream read(String path, int bufferSize) throws IOException;
- InputStream read(String path, OpenMode ... mode) throws IOException;
- InputStream read(String path, int bufferSize, OpenMode ... mode) throws IOException;
+
+ InputStream read(String path, OpenMode... mode) throws IOException;
+
+ InputStream read(String path, int bufferSize, OpenMode... mode) throws IOException;
+
InputStream read(String path, Collection<OpenMode> mode) throws IOException;
+
InputStream read(String path, int bufferSize, Collection<OpenMode> mode) throws IOException;
OutputStream write(String path) throws IOException;
+
OutputStream write(String path, int bufferSize) throws IOException;
- OutputStream write(String path, OpenMode ... mode) throws IOException;
- OutputStream write(String path, int bufferSize, OpenMode ... mode) throws IOException;
+
+ OutputStream write(String path, OpenMode... mode) throws IOException;
+
+ OutputStream write(String path, int bufferSize, OpenMode... mode) throws IOException;
+
OutputStream write(String path, Collection<OpenMode> mode) throws IOException;
+
OutputStream write(String path, int bufferSize, Collection<OpenMode> mode) throws IOException;
/**
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/17f2d627/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpCommand.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpCommand.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpCommand.java
index fea2b6b..d132fe3 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpCommand.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpCommand.java
@@ -45,248 +45,35 @@ import org.apache.sshd.common.util.io.NoCloseInputStream;
/**
* Implements a simple command line SFTP client similar to the Linux one
+ *
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
public class SftpCommand implements Channel {
private final SftpClient client;
+ private final Map<String, CommandExecutor> commandsMap;
private String cwdRemote;
- private final Map<String,CommandExecutor> commandsMap =
- Collections.unmodifiableMap(new TreeMap<String,CommandExecutor>() {
- private static final long serialVersionUID = 1L; // we're not serializing it
-
- {
- for (CommandExecutor e : Arrays.asList(
- new CommandExecutor() {
- @Override
- public String getName() {
- return "exit";
- }
-
- @Override
- public boolean executeCommand(String args, BufferedReader stdin, PrintStream stdout, PrintStream stderr) throws Exception {
- ValidateUtils.checkTrue(GenericUtils.isEmpty(args), "Unexpected arguments: %s", args);
- stdout.println("Exiting");
- return true;
- }
- },
- new CommandExecutor() {
- @Override
- public String getName() {
- return "pwd";
- }
-
- @Override
- public boolean executeCommand(String args, BufferedReader stdin, PrintStream stdout, PrintStream stderr) throws Exception {
- ValidateUtils.checkTrue(GenericUtils.isEmpty(args), "Unexpected arguments: %s", args);
- stdout.append('\t').println(getCurrentRemoteDirectory());
- return false;
- }
- },
- new CommandExecutor() {
- @Override
- public String getName() {
- return "info";
- }
-
- @Override
- public boolean executeCommand(String args, BufferedReader stdin, PrintStream stdout, PrintStream stderr) throws Exception {
- ValidateUtils.checkTrue(GenericUtils.isEmpty(args), "Unexpected arguments: %s", args);
- SftpClient sftp = getClient();
- Map<String,byte[]> extensions = sftp.getServerExtensions();
- Map<String,?> parsed = ParserUtils.parse(extensions);
- for (Map.Entry<String,byte[]> ee : extensions.entrySet()) {
- String name = ee.getKey();
- byte[] value = ee.getValue();
- Object info = parsed.get(name);
-
- stdout.append('\t').append(name).append(": ");
- if (info == null) {
- stdout.println(BufferUtils.printHex(value));
- } else {
- stdout.println(info);
- }
- }
- return false;
- }
- },
- new CommandExecutor() {
- @Override
- public String getName() {
- return "version";
- }
-
- @Override
- public boolean executeCommand(String args, BufferedReader stdin, PrintStream stdout, PrintStream stderr) throws Exception {
- ValidateUtils.checkTrue(GenericUtils.isEmpty(args), "Unexpected arguments: %s", args);
- SftpClient sftp = getClient();
- stdout.append('\t').println(sftp.getVersion());
- return false;
- }
- },
- new CommandExecutor() {
- @Override
- public String getName() {
- return "cd";
- }
-
- @Override
- public boolean executeCommand(String args, BufferedReader stdin, PrintStream stdout, PrintStream stderr) throws Exception {
- ValidateUtils.checkNotNullAndNotEmpty(args, "No remote directory specified", args);
-
- String newPath = resolveRemotePath(args);
- SftpClient sftp = getClient();
- setCurrentRemoteDirectory(sftp.canonicalPath(newPath));
- return false;
- }
- },
- new CommandExecutor() {
- @Override
- public String getName() {
- return "mkdir";
- }
-
- @Override
- public boolean executeCommand(String args, BufferedReader stdin, PrintStream stdout, PrintStream stderr) throws Exception {
- ValidateUtils.checkNotNullAndNotEmpty(args, "No remote directory specified", args);
-
- String path = resolveRemotePath(args);
- SftpClient sftp = getClient();
- sftp.mkdir(path);
- return false;
- }
- },
- new CommandExecutor() {
- @Override
- public String getName() {
- return "ls";
- }
-
- @Override
- public boolean executeCommand(String args, BufferedReader stdin, PrintStream stdout, PrintStream stderr) throws Exception {
- String[] comps = GenericUtils.split(args, ' ');
- // ignore all flag
- String pathArg = GenericUtils.isEmpty(comps) ? null : GenericUtils.trimToEmpty(comps[comps.length - 1]);
- String cwd = getCurrentRemoteDirectory();
- if (GenericUtils.isEmpty(pathArg) || (pathArg.charAt(0) == '-')) {
- pathArg = cwd;
- }
-
- String path = resolveRemotePath(pathArg);
- SftpClient sftp = getClient();
- for (SftpClient.DirEntry entry : sftp.readDir(path)) {
- SftpClient.Attributes attrs = entry.attributes;
- stdout.append('\t').append(entry.filename)
- .append('\t').append(Long.toString(attrs.size))
- .append('\t').println(SftpFileSystemProvider.getRWXPermissions(attrs.perms));
- }
- return false;
- }
- },
- new CommandExecutor() {
- @Override
- public String getName() {
- return "rm";
- }
-
- @Override
- public boolean executeCommand(String args, BufferedReader stdin, PrintStream stdout, PrintStream stderr) throws Exception {
- ValidateUtils.checkNotNullAndNotEmpty(args, "No remote directory specified", args);
-
- String path = resolveRemotePath(args);
- SftpClient sftp = getClient();
- sftp.remove(path);
- return false;
- }
- },
- new CommandExecutor() {
- @Override
- public String getName() {
- return "rmdir";
- }
-
- @Override
- public boolean executeCommand(String args, BufferedReader stdin, PrintStream stdout, PrintStream stderr) throws Exception {
- ValidateUtils.checkNotNullAndNotEmpty(args, "No remote directory specified", args);
-
- String path = resolveRemotePath(args);
- SftpClient sftp = getClient();
- sftp.rmdir(path);
- return false;
- }
- },
- new CommandExecutor() {
- @Override
- public String getName() {
- return "rename";
- }
-
- @Override
- public boolean executeCommand(String args, BufferedReader stdin, PrintStream stdout, PrintStream stderr) throws Exception {
- String[] comps = GenericUtils.split(args, ' ');
- ValidateUtils.checkTrue(GenericUtils.length(comps) == 2, "Invalid number of arguments: %s", args);
-
- String oldPath = resolveRemotePath(GenericUtils.trimToEmpty(comps[0]));
- String newPath = resolveRemotePath(GenericUtils.trimToEmpty(comps[1]));
- SftpClient sftp = getClient();
- sftp.rename(oldPath, newPath);
- return false;
- }
- },
- new CommandExecutor() {
- @Override
- public String getName() {
- return StatVfsExtensionParser.NAME;
- }
-
- @Override
- public boolean executeCommand(String args, BufferedReader stdin, PrintStream stdout, PrintStream stderr) throws Exception {
- String[] comps = GenericUtils.split(args, ' ');
- ValidateUtils.checkTrue(GenericUtils.length(comps) == 1, "Invalid number of arguments: %s", args);
-
- SftpClient sftp = getClient();
- OpenSSHStatPathExtension ext = sftp.getExtension(OpenSSHStatPathExtension.class);
- ValidateUtils.checkTrue(ext.isSupported(), "Extension not supported by server: %s", ext.getName());
-
- OpenSSHStatExtensionInfo info = ext.stat(GenericUtils.trimToEmpty(comps[0]));
- Field[] fields = info.getClass().getFields();
- for (Field f : fields) {
- String name = f.getName();
- int mod = f.getModifiers();
- if (Modifier.isStatic(mod)) {
- continue;
- }
-
- Object value = f.get(info);
- stdout.append('\t').append(name).append(": ").println(value);
- }
-
- return false;
- }
- },
- new CommandExecutor() {
- @Override
- public String getName() {
- return "help";
- }
-
- @Override
- @SuppressWarnings("synthetic-access")
- public boolean executeCommand(String args, BufferedReader stdin, PrintStream stdout, PrintStream stderr) throws Exception {
- ValidateUtils.checkTrue(GenericUtils.isEmpty(args), "Unexpected arguments: %s", args);
- for (String cmd : commandsMap.keySet()) {
- stdout.append('\t').println(cmd);
- }
- return false;
- }
- }
- )) {
- put(e.getName(), e);
- }
- }
- });
public SftpCommand(SftpClient client) {
this.client = ValidateUtils.checkNotNull(client, "No client");
+
+ Map<String, CommandExecutor> map = new TreeMap<>();
+ for (CommandExecutor e : Arrays.asList(
+ new ExitCommandExecutor(),
+ new PwdCommandExecutor(),
+ new InfoCommandExecutor(),
+ new VersionCommandExecutor(),
+ new CdCommandExecutor(),
+ new MkdirCommandExecutor(),
+ new LsCommandExecutor(),
+ new RmCommandExecutor(),
+ new RmdirCommandExecutor(),
+ new RenameCommandExecutor(),
+ new StatVfsCommandExecutor(),
+ new HelpCommandExecutor()
+ )) {
+ map.put(e.getName(), e);
+ }
+ commandsMap = Collections.unmodifiableMap(map);
}
public final SftpClient getClient() {
@@ -296,19 +83,20 @@ public class SftpCommand implements Channel {
public void doInteractive(BufferedReader stdin, PrintStream stdout, PrintStream stderr) throws Exception {
SftpClient sftp = getClient();
setCurrentRemoteDirectory(sftp.canonicalPath("."));
- while(true) {
+ while (true) {
stdout.append(getCurrentRemoteDirectory()).append(" > ").flush();
String line = stdin.readLine();
if (line == null) { // EOF
break;
}
-
+
line = line.trim();
if (GenericUtils.isEmpty(line)) {
continue;
}
-
- String cmd, args;
+
+ String cmd;
+ String args;
int pos = line.indexOf(' ');
if (pos > 0) {
cmd = line.substring(0, pos);
@@ -317,7 +105,7 @@ public class SftpCommand implements Channel {
cmd = line;
args = "";
}
-
+
CommandExecutor exec = commandsMap.get(cmd);
try {
if (exec == null) {
@@ -327,7 +115,7 @@ public class SftpCommand implements Channel {
if (exec.executeCommand(args, stdin, stdout, stderr)) {
break;
}
- } catch(Exception e) {
+ } catch (Exception e) {
stderr.append(e.getClass().getSimpleName()).append(": ").println(e.getMessage());
} finally {
stdout.flush();
@@ -344,13 +132,14 @@ public class SftpCommand implements Channel {
if (GenericUtils.isEmpty(pathArg)) {
return cwd;
}
-
+
if (pathArg.charAt(0) == '/') {
return pathArg;
} else {
return cwd + "/" + pathArg;
}
}
+
public String getCurrentRemoteDirectory() {
return cwdRemote;
}
@@ -373,23 +162,24 @@ public class SftpCommand implements Channel {
public interface CommandExecutor extends NamedResource {
// return value is whether to stop running
- boolean executeCommand(String args, BufferedReader stdin, PrintStream stdout, PrintStream stderr) throws Exception;
+ boolean executeCommand(String args, BufferedReader stdin, PrintStream stdout, PrintStream stderr) throws Exception;
}
//////////////////////////////////////////////////////////////////////////
public static void main(String[] args) throws Exception {
- PrintStream stdout=System.out, stderr=System.err;
- try(BufferedReader stdin = new BufferedReader(new InputStreamReader(new NoCloseInputStream(System.in)))) {
- ClientSession session=SshClient.setupClientSession("-P", stdin, stdout, stderr, args);
+ PrintStream stdout = System.out;
+ PrintStream stderr = System.err;
+ try (BufferedReader stdin = new BufferedReader(new InputStreamReader(new NoCloseInputStream(System.in)))) {
+ ClientSession session = SshClient.setupClientSession("-P", stdin, stdout, stderr, args);
if (session == null) {
System.err.println("usage: sftp [-l login] [-P port] [-o option=value] hostname/user@host");
System.exit(-1);
return;
}
-
- try(SshClient client = (SshClient) session.getFactoryManager()) {
- try(SftpCommand sftp = new SftpCommand(session.createSftpClient())) {
+
+ try {
+ try (SftpCommand sftp = new SftpCommand(session.createSftpClient())) {
sftp.doInteractive(stdin, stdout, stderr);
}
} finally {
@@ -397,4 +187,239 @@ public class SftpCommand implements Channel {
}
}
}
+
+ private static class ExitCommandExecutor implements CommandExecutor {
+ @Override
+ public String getName() {
+ return "exit";
+ }
+
+ @Override
+ public boolean executeCommand(String args, BufferedReader stdin, PrintStream stdout, PrintStream stderr) throws Exception {
+ ValidateUtils.checkTrue(GenericUtils.isEmpty(args), "Unexpected arguments: %s", args);
+ stdout.println("Exiting");
+ return true;
+ }
+ }
+
+ private class PwdCommandExecutor implements CommandExecutor {
+ @Override
+ public String getName() {
+ return "pwd";
+ }
+
+ @Override
+ public boolean executeCommand(String args, BufferedReader stdin, PrintStream stdout, PrintStream stderr) throws Exception {
+ ValidateUtils.checkTrue(GenericUtils.isEmpty(args), "Unexpected arguments: %s", args);
+ stdout.append('\t').println(getCurrentRemoteDirectory());
+ return false;
+ }
+ }
+
+ private class InfoCommandExecutor implements CommandExecutor {
+ @Override
+ public String getName() {
+ return "info";
+ }
+
+ @Override
+ public boolean executeCommand(String args, BufferedReader stdin, PrintStream stdout, PrintStream stderr) throws Exception {
+ ValidateUtils.checkTrue(GenericUtils.isEmpty(args), "Unexpected arguments: %s", args);
+ SftpClient sftp = getClient();
+ Map<String, byte[]> extensions = sftp.getServerExtensions();
+ Map<String, ?> parsed = ParserUtils.parse(extensions);
+ for (Map.Entry<String, byte[]> ee : extensions.entrySet()) {
+ String name = ee.getKey();
+ byte[] value = ee.getValue();
+ Object info = parsed.get(name);
+
+ stdout.append('\t').append(name).append(": ");
+ if (info == null) {
+ stdout.println(BufferUtils.printHex(value));
+ } else {
+ stdout.println(info);
+ }
+ }
+ return false;
+ }
+ }
+
+ private class VersionCommandExecutor implements CommandExecutor {
+ @Override
+ public String getName() {
+ return "version";
+ }
+
+ @Override
+ public boolean executeCommand(String args, BufferedReader stdin, PrintStream stdout, PrintStream stderr) throws Exception {
+ ValidateUtils.checkTrue(GenericUtils.isEmpty(args), "Unexpected arguments: %s", args);
+ SftpClient sftp = getClient();
+ stdout.append('\t').println(sftp.getVersion());
+ return false;
+ }
+ }
+
+ private class CdCommandExecutor implements CommandExecutor {
+ @Override
+ public String getName() {
+ return "cd";
+ }
+
+ @Override
+ public boolean executeCommand(String args, BufferedReader stdin, PrintStream stdout, PrintStream stderr) throws Exception {
+ ValidateUtils.checkNotNullAndNotEmpty(args, "No remote directory specified", args);
+
+ String newPath = resolveRemotePath(args);
+ SftpClient sftp = getClient();
+ setCurrentRemoteDirectory(sftp.canonicalPath(newPath));
+ return false;
+ }
+ }
+
+ private class MkdirCommandExecutor implements CommandExecutor {
+ @Override
+ public String getName() {
+ return "mkdir";
+ }
+
+ @Override
+ public boolean executeCommand(String args, BufferedReader stdin, PrintStream stdout, PrintStream stderr) throws Exception {
+ ValidateUtils.checkNotNullAndNotEmpty(args, "No remote directory specified", args);
+
+ String path = resolveRemotePath(args);
+ SftpClient sftp = getClient();
+ sftp.mkdir(path);
+ return false;
+ }
+ }
+
+ private class LsCommandExecutor implements CommandExecutor {
+ @Override
+ public String getName() {
+ return "ls";
+ }
+
+ @Override
+ public boolean executeCommand(String args, BufferedReader stdin, PrintStream stdout, PrintStream stderr) throws Exception {
+ String[] comps = GenericUtils.split(args, ' ');
+ // ignore all flag
+ String pathArg = GenericUtils.isEmpty(comps) ? null : GenericUtils.trimToEmpty(comps[comps.length - 1]);
+ String cwd = getCurrentRemoteDirectory();
+ if (GenericUtils.isEmpty(pathArg) || (pathArg.charAt(0) == '-')) {
+ pathArg = cwd;
+ }
+
+ String path = resolveRemotePath(pathArg);
+ SftpClient sftp = getClient();
+ for (SftpClient.DirEntry entry : sftp.readDir(path)) {
+ SftpClient.Attributes attrs = entry.attributes;
+ stdout.append('\t').append(entry.filename)
+ .append('\t').append(Long.toString(attrs.size))
+ .append('\t').println(SftpFileSystemProvider.getRWXPermissions(attrs.perms));
+ }
+ return false;
+ }
+ }
+
+ private class RmCommandExecutor implements CommandExecutor {
+ @Override
+ public String getName() {
+ return "rm";
+ }
+
+ @Override
+ public boolean executeCommand(String args, BufferedReader stdin, PrintStream stdout, PrintStream stderr) throws Exception {
+ ValidateUtils.checkNotNullAndNotEmpty(args, "No remote directory specified", args);
+
+ String path = resolveRemotePath(args);
+ SftpClient sftp = getClient();
+ sftp.remove(path);
+ return false;
+ }
+ }
+
+ private class RmdirCommandExecutor implements CommandExecutor {
+ @Override
+ public String getName() {
+ return "rmdir";
+ }
+
+ @Override
+ public boolean executeCommand(String args, BufferedReader stdin, PrintStream stdout, PrintStream stderr) throws Exception {
+ ValidateUtils.checkNotNullAndNotEmpty(args, "No remote directory specified", args);
+
+ String path = resolveRemotePath(args);
+ SftpClient sftp = getClient();
+ sftp.rmdir(path);
+ return false;
+ }
+ }
+
+ private class RenameCommandExecutor implements CommandExecutor {
+ @Override
+ public String getName() {
+ return "rename";
+ }
+
+ @Override
+ public boolean executeCommand(String args, BufferedReader stdin, PrintStream stdout, PrintStream stderr) throws Exception {
+ String[] comps = GenericUtils.split(args, ' ');
+ ValidateUtils.checkTrue(GenericUtils.length(comps) == 2, "Invalid number of arguments: %s", args);
+
+ String oldPath = resolveRemotePath(GenericUtils.trimToEmpty(comps[0]));
+ String newPath = resolveRemotePath(GenericUtils.trimToEmpty(comps[1]));
+ SftpClient sftp = getClient();
+ sftp.rename(oldPath, newPath);
+ return false;
+ }
+ }
+
+ private class StatVfsCommandExecutor implements CommandExecutor {
+ @Override
+ public String getName() {
+ return StatVfsExtensionParser.NAME;
+ }
+
+ @Override
+ public boolean executeCommand(String args, BufferedReader stdin, PrintStream stdout, PrintStream stderr) throws Exception {
+ String[] comps = GenericUtils.split(args, ' ');
+ ValidateUtils.checkTrue(GenericUtils.length(comps) == 1, "Invalid number of arguments: %s", args);
+
+ SftpClient sftp = getClient();
+ OpenSSHStatPathExtension ext = sftp.getExtension(OpenSSHStatPathExtension.class);
+ ValidateUtils.checkTrue(ext.isSupported(), "Extension not supported by server: %s", ext.getName());
+
+ OpenSSHStatExtensionInfo info = ext.stat(GenericUtils.trimToEmpty(comps[0]));
+ Field[] fields = info.getClass().getFields();
+ for (Field f : fields) {
+ String name = f.getName();
+ int mod = f.getModifiers();
+ if (Modifier.isStatic(mod)) {
+ continue;
+ }
+
+ Object value = f.get(info);
+ stdout.append('\t').append(name).append(": ").println(value);
+ }
+
+ return false;
+ }
+ }
+
+ private class HelpCommandExecutor implements CommandExecutor {
+ @Override
+ public String getName() {
+ return "help";
+ }
+
+ @Override
+ @SuppressWarnings("synthetic-access")
+ public boolean executeCommand(String args, BufferedReader stdin, PrintStream stdout, PrintStream stderr) throws Exception {
+ ValidateUtils.checkTrue(GenericUtils.isEmpty(args), "Unexpected arguments: %s", args);
+ for (String cmd : commandsMap.keySet()) {
+ stdout.append('\t').println(cmd);
+ }
+ return false;
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/17f2d627/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileChannel.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileChannel.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileChannel.java
index 19ded8c..ee2671f 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileChannel.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileChannel.java
@@ -18,8 +18,6 @@
*/
package org.apache.sshd.client.subsystem.sftp;
-import static org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FX_LOCK_CONFLICT;
-
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
@@ -46,9 +44,18 @@ import org.apache.sshd.common.util.GenericUtils;
import org.apache.sshd.common.util.ValidateUtils;
import org.apache.sshd.common.util.io.IoUtils;
+import static org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FX_LOCK_CONFLICT;
+
public class SftpFileChannel extends FileChannel {
public static final String COPY_BUFSIZE_PROP = "sftp-channel-copy-buf-size";
- public static final int DEFAULT_TRANSFER_BUFFER_SIZE = IoUtils.DEFAULT_COPY_SIZE;
+ public static final int DEFAULT_TRANSFER_BUFFER_SIZE = IoUtils.DEFAULT_COPY_SIZE;
+
+ public static final Set<SftpClient.OpenMode> READ_MODES =
+ Collections.unmodifiableSet(EnumSet.of(SftpClient.OpenMode.Read));
+
+ public static final Set<SftpClient.OpenMode> WRITE_MODES =
+ Collections.unmodifiableSet(
+ EnumSet.of(SftpClient.OpenMode.Write, SftpClient.OpenMode.Append, SftpClient.OpenMode.Create, SftpClient.OpenMode.Truncate));
private final SftpPath p;
private final Collection<SftpClient.OpenMode> modes;
@@ -61,8 +68,8 @@ public class SftpFileChannel extends FileChannel {
public SftpFileChannel(SftpPath p, Collection<SftpClient.OpenMode> modes) throws IOException {
this.p = ValidateUtils.checkNotNull(p, "No target path");
this.modes = ValidateUtils.checkNotNull(modes, "No channel modes specified");
-
- SftpFileSystem fs=p.getFileSystem();
+
+ SftpFileSystem fs = p.getFileSystem();
sftp = fs.getClient();
handle = sftp.open(p.toString(), modes);
}
@@ -86,9 +93,6 @@ public class SftpFileChannel extends FileChannel {
return doRead(buffers, -1);
}
- public static final Set<SftpClient.OpenMode> READ_MODES=
- Collections.unmodifiableSet(EnumSet.of(SftpClient.OpenMode.Read));
-
protected long doRead(List<ByteBuffer> buffers, long position) throws IOException {
ensureOpen(READ_MODES);
synchronized (lock) {
@@ -124,9 +128,9 @@ public class SftpFileChannel extends FileChannel {
if (totalRead > 0) {
return totalRead;
}
-
+
if (eof) {
- return (-1);
+ return -1;
} else {
return 0;
}
@@ -158,10 +162,6 @@ public class SftpFileChannel extends FileChannel {
return doWrite(buffers, -1);
}
- public static final Set<SftpClient.OpenMode> WRITE_MODES=
- Collections.unmodifiableSet(
- EnumSet.of(SftpClient.OpenMode.Write, SftpClient.OpenMode.Append, SftpClient.OpenMode.Create, SftpClient.OpenMode.Truncate));
-
protected long doWrite(List<ByteBuffer> buffers, long position) throws IOException {
ensureOpen(WRITE_MODES);
synchronized (lock) {
@@ -280,9 +280,9 @@ public class SftpFileChannel extends FileChannel {
boolean completed = false;
long curPos = (position >= 0L) ? position : posTracker.get();
long totalRead = 0L;
- byte[] buffer = new byte[(int) Math.min(copySize,count)];
+ byte[] buffer = new byte[(int) Math.min(copySize, count)];
- synchronized(lock) {
+ synchronized (lock) {
try {
beginBlocking();
@@ -375,22 +375,23 @@ public class SftpFileChannel extends FileChannel {
/**
* Checks that the channel is open and that its current mode contains
* at least one of the required ones
+ *
* @param reqModes The required modes - ignored if {@code null}/empty
* @throws IOException If channel not open or the required modes are not
- * satisfied
+ * satisfied
*/
private void ensureOpen(Collection<SftpClient.OpenMode> reqModes) throws IOException {
if (!isOpen()) {
throw new ClosedChannelException();
}
-
+
if (GenericUtils.size(reqModes) > 0) {
for (SftpClient.OpenMode m : reqModes) {
if (this.modes.contains(m)) {
return;
}
}
-
+
throw new IOException("ensureOpen(" + p + ") current channel modes (" + this.modes + ") do contain any of the required: " + reqModes);
}
}