You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by lg...@apache.org on 2018/01/03 18:30:45 UTC
mina-sshd git commit: [SSHD-790] Added capability to encode outgoing
SFTP client names with non default charset
Repository: mina-sshd
Updated Branches:
refs/heads/master 642a8f3b2 -> ec901de77
[SSHD-790] Added capability to encode outgoing SFTP client names with non default charset
Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/ec901de7
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/ec901de7
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/ec901de7
Branch: refs/heads/master
Commit: ec901de77fb2da687c4882f057ec330352c2e5ff
Parents: 642a8f3
Author: Lyor Goldstein <ly...@gmail.com>
Authored: Wed Jan 3 20:32:24 2018 +0200
Committer: Lyor Goldstein <ly...@gmail.com>
Committed: Wed Jan 3 20:32:54 2018 +0200
----------------------------------------------------------------------
README.md | 13 ++-
.../client/subsystem/sftp/SftpFileSystem.java | 1 -
.../subsystem/sftp/impl/AbstractSftpClient.java | 74 ++++++++++------
.../sshd/common/subsystem/sftp/SftpHelper.java | 92 ++++++++++++--------
4 files changed, 113 insertions(+), 67 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/ec901de7/README.md
----------------------------------------------------------------------
diff --git a/README.md b/README.md
index 4e99d3e..5cc741f 100644
--- a/README.md
+++ b/README.md
@@ -732,10 +732,10 @@ throughout the SFTP server subsystem code. The accessor is registered/overwritte
```
-### SFTP received names encoding
+### SFTP sent/received names encoding
-By default, the SFTP client uses UTF-8 to decode any referenced file/folder name. However, some servers do not properly encode such names, and
-thus the "decoded" names by the client become corrupted, or even worse - cause an exception upon decoding attempt. The `SftpClient` exposes
+By default, the SFTP client uses UTF-8 to encode/decode any referenced file/folder name. However, some servers do not properly encode such names,
+and thus the "visible" names by the client become corrupted, or even worse - cause an exception upon decoding attempt. The `SftpClient` exposes
a `get/setNameDecodingCharset` method which enables the user to modify the charset - even while the SFTP session is in progress - e.g.:
```java
@@ -799,6 +799,13 @@ public class MyCustomSftpClient extends DefaultSftpClient {
Charset cs = detectCharset(bytes);
return new String(bytes, cs);
}
+
+ @Override
+ protected <B extends Buffer> B putReferencedName(int cmd, B buf, String name) {
+ Charset cs = detectCharset(name);
+ buf.putString(name, cs);
+ return buf;
+ }
}
public class MyCustomSftpClientFactory extends DefaultSftpClientFactory {
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/ec901de7/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystem.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystem.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystem.java
index 1ca0283..bc790b3 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystem.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystem.java
@@ -210,7 +210,6 @@ public class SftpFileSystem extends BaseFileSystem<SftpPath> implements ClientSe
}
private final class Wrapper extends AbstractSftpClient {
-
private final SftpClient delegate;
private final AtomicInteger count = new AtomicInteger(1);
private final int readSize;
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/ec901de7/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/impl/AbstractSftpClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/impl/AbstractSftpClient.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/impl/AbstractSftpClient.java
index a1d2014..45173e2 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/impl/AbstractSftpClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/impl/AbstractSftpClient.java
@@ -119,6 +119,19 @@ public abstract class AbstractSftpClient extends AbstractSubsystemClient impleme
}
/**
+ * @param <B> Type of {@link Buffer} being updated
+ * @param cmd The command for which this name is being added
+ * @param buf The buffer instance to update
+ * @param name The name to place in the buffer
+ * @return The updated buffer
+ */
+ protected <B extends Buffer> B putReferencedName(int cmd, B buf, String name) {
+ Charset cs = getNameDecodingCharset();
+ buf.putString(name, cs);
+ return buf;
+ }
+
+ /**
* Sends the specified command, waits for the response and then invokes {@link #checkResponseStatus(int, Buffer)}
* @param cmd The command to send
* @param request The request {@link Buffer}
@@ -444,7 +457,7 @@ public abstract class AbstractSftpClient extends AbstractSubsystemClient impleme
return attrs;
}
- protected void writeAttributes(Buffer buffer, Attributes attributes) throws IOException {
+ protected <B extends Buffer> B writeAttributes(int cmd, B buffer, Attributes attributes) throws IOException {
int version = getVersion();
int flagsMask = 0;
Collection<Attribute> flags = Objects.requireNonNull(attributes, "No attributes").getFlags();
@@ -489,8 +502,8 @@ public abstract class AbstractSftpClient extends AbstractSubsystemClient impleme
}
if ((flagsMask & SftpConstants.SSH_FILEXFER_ATTR_ACMODTIME) != 0) {
- SftpHelper.writeTime(buffer, version, flagsMask, attributes.getAccessTime());
- SftpHelper.writeTime(buffer, version, flagsMask, attributes.getModifyTime());
+ buffer = SftpHelper.writeTime(buffer, version, flagsMask, attributes.getAccessTime());
+ buffer = SftpHelper.writeTime(buffer, version, flagsMask, attributes.getModifyTime());
}
} else if (version >= SftpConstants.SFTP_V4) {
for (Attribute a : flags) {
@@ -538,26 +551,28 @@ public abstract class AbstractSftpClient extends AbstractSubsystemClient impleme
buffer.putInt(attributes.getPermissions());
}
if ((flagsMask & SftpConstants.SSH_FILEXFER_ATTR_ACCESSTIME) != 0) {
- SftpHelper.writeTime(buffer, version, flagsMask, attributes.getAccessTime());
+ buffer = SftpHelper.writeTime(buffer, version, flagsMask, attributes.getAccessTime());
}
if ((flagsMask & SftpConstants.SSH_FILEXFER_ATTR_CREATETIME) != 0) {
- SftpHelper.writeTime(buffer, version, flagsMask, attributes.getCreateTime());
+ buffer = SftpHelper.writeTime(buffer, version, flagsMask, attributes.getCreateTime());
}
if ((flagsMask & SftpConstants.SSH_FILEXFER_ATTR_MODIFYTIME) != 0) {
- SftpHelper.writeTime(buffer, version, flagsMask, attributes.getModifyTime());
+ buffer = SftpHelper.writeTime(buffer, version, flagsMask, attributes.getModifyTime());
}
if ((flagsMask & SftpConstants.SSH_FILEXFER_ATTR_ACL) != 0) {
- SftpHelper.writeACLs(buffer, version, attributes.getAcl());
+ buffer = SftpHelper.writeACLs(buffer, version, attributes.getAcl());
}
- // TODO: for v6+ add CTIME (see https://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#page-21)
+ // TODO: for v5 ? 6? add CTIME (see https://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#page-16 - v6)
} else {
throw new UnsupportedOperationException("writeAttributes(" + attributes + ") unsupported version: " + version);
}
if ((flagsMask & SftpConstants.SSH_FILEXFER_ATTR_EXTENDED) != 0) {
- SftpHelper.writeExtensions(buffer, attributes.getExtensions());
+ buffer = SftpHelper.writeExtensions(buffer, attributes.getExtensions());
}
+
+ return buffer;
}
@Override
@@ -574,7 +589,8 @@ public abstract class AbstractSftpClient extends AbstractSubsystemClient impleme
}
Buffer buffer = new ByteArrayBuffer(path.length() + Long.SIZE /* some extra fields */, false);
- buffer.putString(path);
+ buffer = putReferencedName(SftpConstants.SSH_FXP_OPEN, buffer, path);
+
int version = getVersion();
int mode = 0;
if (version < SftpConstants.SFTP_V5) {
@@ -627,7 +643,7 @@ public abstract class AbstractSftpClient extends AbstractSubsystemClient impleme
}
}
buffer.putInt(mode);
- writeAttributes(buffer, fileOpenAttributes);
+ buffer = writeAttributes(SftpConstants.SSH_FXP_OPEN, buffer, fileOpenAttributes);
CloseableHandle handle = new DefaultCloseableHandle(this, path, checkHandle(SftpConstants.SSH_FXP_OPEN, buffer));
if (log.isTraceEnabled()) {
@@ -663,7 +679,7 @@ public abstract class AbstractSftpClient extends AbstractSubsystemClient impleme
}
Buffer buffer = new ByteArrayBuffer(path.length() + Long.SIZE /* some extra fields */, false);
- buffer.putString(path);
+ buffer = putReferencedName(SftpConstants.SSH_FXP_REMOVE, buffer, path);
checkCommandStatus(SftpConstants.SSH_FXP_REMOVE, buffer);
}
@@ -678,8 +694,8 @@ public abstract class AbstractSftpClient extends AbstractSubsystemClient impleme
}
Buffer buffer = new ByteArrayBuffer(oldPath.length() + newPath.length() + Long.SIZE /* some extra fields */, false);
- buffer.putString(oldPath);
- buffer.putString(newPath);
+ buffer = putReferencedName(SftpConstants.SSH_FXP_RENAME, buffer, oldPath);
+ buffer = putReferencedName(SftpConstants.SSH_FXP_RENAME, buffer, newPath);
int numOptions = GenericUtils.size(options);
int version = getVersion();
@@ -827,7 +843,7 @@ public abstract class AbstractSftpClient extends AbstractSubsystemClient impleme
}
Buffer buffer = new ByteArrayBuffer(path.length() + Long.SIZE /* some extra fields */, false);
- buffer.putString(path);
+ buffer = putReferencedName(SftpConstants.SSH_FXP_MKDIR, buffer, path);
buffer.putInt(0);
int version = getVersion();
@@ -849,7 +865,7 @@ public abstract class AbstractSftpClient extends AbstractSubsystemClient impleme
}
Buffer buffer = new ByteArrayBuffer(path.length() + Long.SIZE /* some extra fields */, false);
- buffer.putString(path);
+ buffer = putReferencedName(SftpConstants.SSH_FXP_RMDIR, buffer, path);
checkCommandStatus(SftpConstants.SSH_FXP_RMDIR, buffer);
}
@@ -860,7 +876,7 @@ public abstract class AbstractSftpClient extends AbstractSubsystemClient impleme
}
Buffer buffer = new ByteArrayBuffer(path.length() + Long.SIZE /* some extra fields */, false);
- buffer.putString(path);
+ buffer = putReferencedName(SftpConstants.SSH_FXP_OPENDIR, buffer, path);
CloseableHandle handle = new DefaultCloseableHandle(this, path, checkHandle(SftpConstants.SSH_FXP_OPENDIR, buffer));
if (log.isTraceEnabled()) {
@@ -968,7 +984,7 @@ public abstract class AbstractSftpClient extends AbstractSubsystemClient impleme
}
Buffer buffer = new ByteArrayBuffer(path.length() + Long.SIZE, false);
- buffer.putString(path);
+ buffer = putReferencedName(SftpConstants.SSH_FXP_REALPATH, buffer, path);
return checkOneName(SftpConstants.SSH_FXP_REALPATH, buffer);
}
@@ -979,7 +995,7 @@ public abstract class AbstractSftpClient extends AbstractSubsystemClient impleme
}
Buffer buffer = new ByteArrayBuffer(path.length() + Long.SIZE, false);
- buffer.putString(path);
+ buffer = putReferencedName(SftpConstants.SSH_FXP_STAT, buffer, path);
int version = getVersion();
if (version >= SftpConstants.SFTP_V4) {
@@ -996,7 +1012,7 @@ public abstract class AbstractSftpClient extends AbstractSubsystemClient impleme
}
Buffer buffer = new ByteArrayBuffer(path.length() + Long.SIZE, false);
- buffer.putString(path);
+ buffer = putReferencedName(SftpConstants.SSH_FXP_LSTAT, buffer, path);
int version = getVersion();
if (version >= SftpConstants.SFTP_V4) {
@@ -1035,8 +1051,8 @@ public abstract class AbstractSftpClient extends AbstractSubsystemClient impleme
}
Buffer buffer = new ByteArrayBuffer();
- buffer.putString(path);
- writeAttributes(buffer, attributes);
+ buffer = putReferencedName(SftpConstants.SSH_FXP_SETSTAT, buffer, path);
+ buffer = writeAttributes(SftpConstants.SSH_FXP_SETSTAT, buffer, attributes);
checkCommandStatus(SftpConstants.SSH_FXP_SETSTAT, buffer);
}
@@ -1052,7 +1068,7 @@ public abstract class AbstractSftpClient extends AbstractSubsystemClient impleme
byte[] id = Objects.requireNonNull(handle, "No handle").getIdentifier();
Buffer buffer = new ByteArrayBuffer(id.length + (2 * Long.SIZE) /* some extras */, false);
buffer.putBytes(id);
- writeAttributes(buffer, attributes);
+ buffer = writeAttributes(SftpConstants.SSH_FXP_FSETSTAT, buffer, attributes);
checkCommandStatus(SftpConstants.SSH_FXP_FSETSTAT, buffer);
}
@@ -1063,7 +1079,7 @@ public abstract class AbstractSftpClient extends AbstractSubsystemClient impleme
}
Buffer buffer = new ByteArrayBuffer(path.length() + Long.SIZE /* some extra fields */, false);
- buffer.putString(path);
+ buffer = putReferencedName(SftpConstants.SSH_FXP_READLINK, buffer, path);
return checkOneName(SftpConstants.SSH_FXP_READLINK, buffer);
}
@@ -1083,13 +1099,15 @@ public abstract class AbstractSftpClient extends AbstractSubsystemClient impleme
if (!symbolic) {
throw new UnsupportedOperationException("Hard links are not supported in sftp v" + version);
}
- buffer.putString(targetPath);
- buffer.putString(linkPath);
+ buffer = putReferencedName(SftpConstants.SSH_FXP_SYMLINK, buffer, targetPath);
+ buffer = putReferencedName(SftpConstants.SSH_FXP_SYMLINK, buffer, linkPath);
+
checkCommandStatus(SftpConstants.SSH_FXP_SYMLINK, buffer);
} else {
- buffer.putString(targetPath);
- buffer.putString(linkPath);
+ buffer = putReferencedName(SftpConstants.SSH_FXP_SYMLINK, buffer, targetPath);
+ buffer = putReferencedName(SftpConstants.SSH_FXP_SYMLINK, buffer, linkPath);
buffer.putBoolean(symbolic);
+
checkCommandStatus(SftpConstants.SSH_FXP_LINK, buffer);
}
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/ec901de7/sshd-core/src/main/java/org/apache/sshd/common/subsystem/sftp/SftpHelper.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/subsystem/sftp/SftpHelper.java b/sshd-core/src/main/java/org/apache/sshd/common/subsystem/sftp/SftpHelper.java
index 7b06e11..5f83818 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/subsystem/sftp/SftpHelper.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/subsystem/sftp/SftpHelper.java
@@ -195,17 +195,19 @@ public final class SftpHelper {
/**
* Writes a file / folder's attributes to a buffer
*
- * @param buffer The target {@link Buffer}
+ * @param <B> Type of {@link Buffer} being updated
+ * @param buffer The target buffer instance
* @param version The output encoding version
* @param attributes The {@link Map} of attributes
+ * @return The updated buffer
* @see #writeAttrsV3(Buffer, int, Map)
* @see #writeAttrsV4(Buffer, int, Map)
*/
- public static void writeAttrs(Buffer buffer, int version, Map<String, ?> attributes) {
+ public static <B extends Buffer> B writeAttrs(B buffer, int version, Map<String, ?> attributes) {
if (version == SftpConstants.SFTP_V3) {
- writeAttrsV3(buffer, version, attributes);
+ return writeAttrsV3(buffer, version, attributes);
} else if (version >= SftpConstants.SFTP_V4) {
- writeAttrsV4(buffer, version, attributes);
+ return writeAttrsV4(buffer, version, attributes);
} else {
throw new IllegalStateException("Unsupported SFTP version: " + version);
}
@@ -214,11 +216,13 @@ public final class SftpHelper {
/**
* Writes the retrieved file / directory attributes in V3 format
*
- * @param buffer The target {@link Buffer}
+ * @param <B> Type of {@link Buffer} being updated
+ * @param buffer The target buffer instance
* @param version The actual version - must be {@link SftpConstants#SFTP_V3}
* @param attributes The {@link Map} of attributes
+ * @return The updated buffer
*/
- public static void writeAttrsV3(Buffer buffer, int version, Map<String, ?> attributes) {
+ public static <B extends Buffer> B writeAttrsV3(B buffer, int version, Map<String, ?> attributes) {
ValidateUtils.checkTrue(version == SftpConstants.SFTP_V3, "Illegal version: %d", version);
boolean isReg = getBool((Boolean) attributes.get("isRegularFile"));
@@ -247,22 +251,26 @@ public final class SftpHelper {
buffer.putInt(attributesToPermissions(isReg, isDir, isLnk, perms));
}
if ((flags & SftpConstants.SSH_FILEXFER_ATTR_ACMODTIME) != 0) {
- writeTime(buffer, version, flags, lastAccessTime);
- writeTime(buffer, version, flags, lastModifiedTime);
+ buffer = writeTime(buffer, version, flags, lastAccessTime);
+ buffer = writeTime(buffer, version, flags, lastModifiedTime);
}
if ((flags & SftpConstants.SSH_FILEXFER_ATTR_EXTENDED) != 0) {
- writeExtensions(buffer, extensions);
+ buffer = writeExtensions(buffer, extensions);
}
+
+ return buffer;
}
/**
* Writes the retrieved file / directory attributes in V4+ format
*
- * @param buffer The target {@link Buffer}
+ * @param <B> Type of {@link Buffer} being updated
+ * @param buffer The target buffer instance
* @param version The actual version - must be at least {@link SftpConstants#SFTP_V4}
* @param attributes The {@link Map} of attributes
+ * @return The updated buffer
*/
- public static void writeAttrsV4(Buffer buffer, int version, Map<String, ?> attributes) {
+ public static <B extends Buffer> B writeAttrsV4(B buffer, int version, Map<String, ?> attributes) {
ValidateUtils.checkTrue(version >= SftpConstants.SFTP_V4, "Illegal version: %d", version);
boolean isReg = getBool((Boolean) attributes.get("isRegularFile"));
@@ -302,23 +310,25 @@ public final class SftpHelper {
}
if ((flags & SftpConstants.SSH_FILEXFER_ATTR_ACCESSTIME) != 0) {
- writeTime(buffer, version, flags, lastAccessTime);
+ buffer = writeTime(buffer, version, flags, lastAccessTime);
}
if ((flags & SftpConstants.SSH_FILEXFER_ATTR_CREATETIME) != 0) {
- writeTime(buffer, version, flags, lastAccessTime);
+ buffer = writeTime(buffer, version, flags, lastAccessTime);
}
if ((flags & SftpConstants.SSH_FILEXFER_ATTR_MODIFYTIME) != 0) {
- writeTime(buffer, version, flags, lastModifiedTime);
+ buffer = writeTime(buffer, version, flags, lastModifiedTime);
}
if ((flags & SftpConstants.SSH_FILEXFER_ATTR_ACL) != 0) {
- writeACLs(buffer, version, acl);
+ buffer = writeACLs(buffer, version, acl);
}
// TODO: ctime
// TODO: bits
if ((flags & SftpConstants.SSH_FILEXFER_ATTR_EXTENDED) != 0) {
- writeExtensions(buffer, extensions);
+ buffer = writeExtensions(buffer, extensions);
}
+
+ return buffer;
}
/**
@@ -644,21 +654,25 @@ public final class SftpHelper {
return extended;
}
- public static void writeExtensions(Buffer buffer, Map<?, ?> extensions) {
+ public static <B extends Buffer> B writeExtensions(B buffer, Map<?, ?> extensions) {
int numExtensions = GenericUtils.size(extensions);
buffer.putInt(numExtensions);
- if (numExtensions > 0) {
- extensions.forEach((key, value) -> {
- Objects.requireNonNull(key, "No extension type");
- Objects.requireNonNull(value, "No extension value");
- buffer.putString(key.toString());
- if (value instanceof byte[]) {
- buffer.putBytes((byte[]) value);
- } else {
- buffer.putString(value.toString());
- }
- });
+ if (numExtensions <= 0) {
+ return buffer;
}
+
+ extensions.forEach((key, value) -> {
+ Objects.requireNonNull(key, "No extension type");
+ Objects.requireNonNull(value, "No extension value");
+ buffer.putString(key.toString());
+ if (value instanceof byte[]) {
+ buffer.putBytes((byte[]) value);
+ } else {
+ buffer.putString(value.toString());
+ }
+ });
+
+ return buffer;
}
public static NavigableMap<String, String> toStringExtensions(Map<String, ?> extensions) {
@@ -834,14 +848,15 @@ public final class SftpHelper {
return mask;
}
- public static void writeACLs(Buffer buffer, int version, Collection<? extends AclEntry> acl) {
+ public static <B extends Buffer> B writeACLs(B buffer, int version, Collection<? extends AclEntry> acl) {
int lenPos = buffer.wpos();
buffer.putInt(0); // length placeholder
- encodeACLs(buffer, version, acl);
+ buffer = encodeACLs(buffer, version, acl);
BufferUtils.updateLengthPlaceholder(buffer, lenPos);
+ return buffer;
}
- public static void encodeACLs(Buffer buffer, int version, Collection<? extends AclEntry> acl) {
+ public static <B extends Buffer> B encodeACLs(B buffer, int version, Collection<? extends AclEntry> acl) {
Objects.requireNonNull(acl, "No ACL");
if (version >= SftpConstants.SFTP_V6) {
buffer.putInt(0); // TODO handle ACL flags
@@ -851,12 +866,14 @@ public final class SftpHelper {
buffer.putInt(numEntries);
if (numEntries > 0) {
for (AclEntry e : acl) {
- writeAclEntry(buffer, e);
+ buffer = writeAclEntry(buffer, e);
}
}
+
+ return buffer;
}
- public static void writeAclEntry(Buffer buffer, AclEntry acl) {
+ public static <B extends Buffer> B writeAclEntry(B buffer, AclEntry acl) {
Objects.requireNonNull(acl, "No ACL");
AclEntryType type = acl.type();
@@ -868,6 +885,7 @@ public final class SftpHelper {
Principal user = acl.principal();
buffer.putString(user.getName());
+ return buffer;
}
/**
@@ -982,12 +1000,14 @@ public final class SftpHelper {
/**
* Encodes a {@link FileTime} value into a buffer
*
- * @param buffer The target {@link Buffer}
+ * @param <B> Type of {@link Buffer} being updated
+ * @param buffer The target buffer instance
* @param version The encoding version
* @param flags The encoding flags
* @param time The value to encode
+ * @return The updated buffer
*/
- public static void writeTime(Buffer buffer, int version, int flags, FileTime time) {
+ public static <B extends Buffer> B writeTime(B buffer, int version, int flags, FileTime time) {
// for v3 see https://tools.ietf.org/html/draft-ietf-secsh-filexfer-02#page-8
// for v6 see https://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#page-16
if (version >= SftpConstants.SFTP_V4) {
@@ -1000,6 +1020,8 @@ public final class SftpHelper {
} else {
buffer.putInt(time.to(TimeUnit.SECONDS));
}
+
+ return buffer;
}
/**