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 2013/07/18 15:33:28 UTC

git commit: [SSHD-236] Support SSH_FXP_REALPATH options

Updated Branches:
  refs/heads/master 6daaea9b3 -> afdfca0e5


[SSHD-236] Support SSH_FXP_REALPATH options

Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/afdfca0e
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/afdfca0e
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/afdfca0e

Branch: refs/heads/master
Commit: afdfca0e534783472a1767afd547500855a1fa47
Parents: 6daaea9
Author: Guillaume Nodet <gn...@apache.org>
Authored: Thu Jul 18 15:33:18 2013 +0200
Committer: Guillaume Nodet <gn...@apache.org>
Committed: Thu Jul 18 15:33:18 2013 +0200

----------------------------------------------------------------------
 .../apache/sshd/server/sftp/SftpSubsystem.java  | 36 ++++++++++++++++----
 .../sftp/request/SshFxpRealpathRequest.java     | 16 ++++++++-
 .../apache/sshd/sftp/subsystem/Serializer.java  | 12 ++++++-
 .../sshd/sftp/subsystem/SftpConstants.java      |  4 +++
 .../sshd/sftp/subsystem/SftpSubsystem.java      | 22 ++++++++----
 5 files changed, 74 insertions(+), 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/afdfca0e/sshd-core/src/main/java/org/apache/sshd/server/sftp/SftpSubsystem.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/sftp/SftpSubsystem.java b/sshd-core/src/main/java/org/apache/sshd/server/sftp/SftpSubsystem.java
index 5615063..687369f 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/sftp/SftpSubsystem.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/sftp/SftpSubsystem.java
@@ -21,10 +21,12 @@ package org.apache.sshd.server.sftp;
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
 import java.io.EOFException;
+import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.Date;
 import java.util.GregorianCalendar;
@@ -204,6 +206,10 @@ public class SftpSubsystem implements Command, Runnable, SessionAware, FileSyste
     public static final int SSH_FXF_EXCL = 0x00000020;
     public static final int SSH_FXF_TEXT = 0x00000040;
 
+    public static final int SSH_FXP_REALPATH_NO_CHECK =    0x00000001;
+    public static final int SSH_FXP_REALPATH_STAT_IF =     0x00000002;
+    public static final int SSH_FXP_REALPATH_STAT_ALWAYS = 0x00000003;
+
     public static final int ACE4_READ_DATA = 0x00000001;
     public static final int ACE4_LIST_DIRECTORY = 0x00000001;
     public static final int ACE4_WRITE_DATA = 0x00000002;
@@ -895,10 +901,20 @@ public class SftpSubsystem implements Command, Runnable, SessionAware, FileSyste
                 if (path.trim().length() == 0) {
                     path = ".";
                 }
-                // TODO: handle optional args
+                byte options = SSH_FXP_REALPATH_NO_CHECK;
+                List<String> compose = new ArrayList<String>();
+                if (version >= 6 && buffer.available() > 0) {
+                    options = buffer.getByte();
+                }
+                while (version >= 6 && buffer.available() > 0) {
+                    compose.add(buffer.getString());
+                }
                 try {
                     SshFile p = resolveFile(path);
-                    sendPath(id, p);
+                    for (String s : compose) {
+                        p = this.root.getFile(p, s);
+                    }
+                    sendPath(id, p, options);
                 } catch (FileNotFoundException e) {
                     e.printStackTrace();
                     sendStatus(id, SSH_FX_NO_SUCH_FILE, e.getMessage());
@@ -970,7 +986,7 @@ public class SftpSubsystem implements Command, Runnable, SessionAware, FileSyste
     }
 
 
-    protected void sendPath(int id, SshFile f) throws IOException {
+    protected void sendPath(int id, SshFile f, byte options) throws IOException {
         Buffer buffer = new Buffer();
         buffer.putByte((byte) SSH_FXP_NAME);
         buffer.putInt(id);
@@ -985,12 +1001,18 @@ public class SftpSubsystem implements Command, Runnable, SessionAware, FileSyste
         if (f.getName().length() == 0) {
             f = resolveFile(".");
         }
-        if (version <= 3) {
-            buffer.putString(getLongName(f)); // Format specified in the specs
-            buffer.putInt(0);
-        } else {
+        if (options == SSH_FXP_REALPATH_STAT_IF && f.doesExist() || options == SSH_FXP_REALPATH_STAT_ALWAYS) {
             buffer.putString(f.getName()); // Supposed to be UTF-8
             writeAttrs(buffer, f);
+        } else {
+            if (version <= 3) {
+                buffer.putString(getLongName(f)); // Format specified in the specs
+                buffer.putInt(0);
+            } else if (version >= 4 || options == SSH_FXP_REALPATH_NO_CHECK) {
+                buffer.putString(f.getName());
+                buffer.putInt(0);
+                buffer.putByte((byte) 0);
+            }
         }
         send(buffer);
     }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/afdfca0e/sshd-sftp/src/main/java/org/apache/sshd/sftp/request/SshFxpRealpathRequest.java
----------------------------------------------------------------------
diff --git a/sshd-sftp/src/main/java/org/apache/sshd/sftp/request/SshFxpRealpathRequest.java b/sshd-sftp/src/main/java/org/apache/sshd/sftp/request/SshFxpRealpathRequest.java
index 623834e..064c651 100644
--- a/sshd-sftp/src/main/java/org/apache/sshd/sftp/request/SshFxpRealpathRequest.java
+++ b/sshd-sftp/src/main/java/org/apache/sshd/sftp/request/SshFxpRealpathRequest.java
@@ -18,6 +18,8 @@
 */
 package org.apache.sshd.sftp.request;
 
+import java.util.List;
+
 import org.apache.sshd.sftp.subsystem.SftpConstants;
 
 /**
@@ -27,6 +29,8 @@ import org.apache.sshd.sftp.subsystem.SftpConstants;
  */
 public class SshFxpRealpathRequest extends BaseRequest {
 	private final String path;
+    private final byte options;
+    private final List<String> compose;
 
 	/**
 	 * Creates a SshFxpRealpathRequest instance.
@@ -34,9 +38,11 @@ public class SshFxpRealpathRequest extends BaseRequest {
 	 * @param id   The request id.
 	 * @param path The requested file path.
 	 */
-	public SshFxpRealpathRequest(final int id, final String path) {
+	public SshFxpRealpathRequest(final int id, final String path, final byte options, final List<String> compose) {
 		super(id);
 		this.path = path;
+        this.options = options;
+        this.compose = compose;
 	}
 
 	/**
@@ -61,4 +67,12 @@ public class SshFxpRealpathRequest extends BaseRequest {
 	public String getPath() {
 		return path;
 	}
+
+    public byte getOptions() {
+        return options;
+    }
+
+    public List<String> getCompose() {
+        return compose;
+    }
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/afdfca0e/sshd-sftp/src/main/java/org/apache/sshd/sftp/subsystem/Serializer.java
----------------------------------------------------------------------
diff --git a/sshd-sftp/src/main/java/org/apache/sshd/sftp/subsystem/Serializer.java b/sshd-sftp/src/main/java/org/apache/sshd/sftp/subsystem/Serializer.java
index 4b49cfc..4ad3056 100644
--- a/sshd-sftp/src/main/java/org/apache/sshd/sftp/subsystem/Serializer.java
+++ b/sshd-sftp/src/main/java/org/apache/sshd/sftp/subsystem/Serializer.java
@@ -28,10 +28,12 @@ import org.apache.sshd.sftp.reply.*;
 import org.apache.sshd.sftp.request.*;
 
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.Collection;
 import java.util.GregorianCalendar;
 import java.util.Iterator;
+import java.util.List;
 
 import static org.apache.sshd.sftp.subsystem.SftpConstants.*;
 import static org.apache.sshd.sftp.subsystem.SftpConstants.SSH_FXP_STATUS;
@@ -143,7 +145,15 @@ public class Serializer {
             }
             case SSH_FXP_REALPATH: {
                 String path = buffer.getString();
-                request = new SshFxpRealpathRequest(id, path);
+                byte options = SSH_FXP_REALPATH_NO_CHECK;
+                List<String> compose = new ArrayList<String>();
+                if (session.getVersion() >= 6 && buffer.available() > 0) {
+                    options = buffer.getByte();
+                }
+                while (session.getVersion() >= 6 && buffer.available() > 0) {
+                    compose.add(buffer.getString());
+                }
+                request = new SshFxpRealpathRequest(id, path, options, compose);
                 break;
             }
             case SSH_FXP_STAT: {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/afdfca0e/sshd-sftp/src/main/java/org/apache/sshd/sftp/subsystem/SftpConstants.java
----------------------------------------------------------------------
diff --git a/sshd-sftp/src/main/java/org/apache/sshd/sftp/subsystem/SftpConstants.java b/sshd-sftp/src/main/java/org/apache/sshd/sftp/subsystem/SftpConstants.java
index 3c4ac15..0b4ae4a 100644
--- a/sshd-sftp/src/main/java/org/apache/sshd/sftp/subsystem/SftpConstants.java
+++ b/sshd-sftp/src/main/java/org/apache/sshd/sftp/subsystem/SftpConstants.java
@@ -268,6 +268,10 @@ public final class SftpConstants {
     public static final int SSH_FXF_EXCL = 0x00000020;
     public static final int SSH_FXF_TEXT = 0x00000040;
 
+    public static final int SSH_FXP_REALPATH_NO_CHECK =    0x00000001;
+    public static final int SSH_FXP_REALPATH_STAT_IF =     0x00000002;
+    public static final int SSH_FXP_REALPATH_STAT_ALWAYS = 0x00000003;
+
     public static final int ACE4_READ_DATA = 0x00000001;
     public static final int ACE4_LIST_DIRECTORY = 0x00000001;
     public static final int ACE4_WRITE_DATA = 0x00000002;

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/afdfca0e/sshd-sftp/src/main/java/org/apache/sshd/sftp/subsystem/SftpSubsystem.java
----------------------------------------------------------------------
diff --git a/sshd-sftp/src/main/java/org/apache/sshd/sftp/subsystem/SftpSubsystem.java b/sshd-sftp/src/main/java/org/apache/sshd/sftp/subsystem/SftpSubsystem.java
index 3729ae0..09ce672 100644
--- a/sshd-sftp/src/main/java/org/apache/sshd/sftp/subsystem/SftpSubsystem.java
+++ b/sshd-sftp/src/main/java/org/apache/sshd/sftp/subsystem/SftpSubsystem.java
@@ -307,10 +307,9 @@ public class SftpSubsystem implements Command, SessionAware, FileSystemAware, Sf
         if (path.trim().length() == 0) {
             path = ".";
         }
-        // TODO: handle optional args
         SshFile p = resolveFile(path);
-        if (!p.doesExist()) {
-            return new SshFxpStatusReply(id, SSH_FX_NO_SUCH_FILE, p.getAbsolutePath());
+        for (String s : request.getCompose()) {
+            p = this.root.getFile(p, s);
         }
         String normalizedPath = SelectorUtils.normalizePath(p.getAbsolutePath(), "/");
         if (normalizedPath.length() == 0) {
@@ -320,10 +319,19 @@ public class SftpSubsystem implements Command, SessionAware, FileSystemAware, Sf
         if (p.getName().length() == 0) {
             p = resolveFile(".");
         }
-        SshFxpNameReply reply = new SshFxpNameReply(id);
-        int flags = SSH_FILEXFER_ATTR_PERMISSIONS | SSH_FILEXFER_ATTR_SIZE;
-        reply.addFile(p, normalizedPath, getLongName(p), new FileAttributes(p, flags));
-        return reply;
+        boolean exists = (request.getOptions() != SSH_FXP_REALPATH_NO_CHECK) && p.doesExist();
+        if (!exists && request.getOptions() == SSH_FXP_REALPATH_STAT_ALWAYS) {
+            return new SshFxpStatusReply(id, SSH_FX_NO_SUCH_FILE, p.getAbsolutePath());
+        } else if (exists && (request.getOptions() == SSH_FXP_REALPATH_STAT_IF || request.getOptions() == SSH_FXP_REALPATH_STAT_ALWAYS)) {
+            SshFxpNameReply reply = new SshFxpNameReply(id);
+            int flags = SSH_FILEXFER_ATTR_PERMISSIONS | SSH_FILEXFER_ATTR_SIZE;
+            reply.addFile(p, normalizedPath, getLongName(p), new FileAttributes(p, flags));
+            return reply;
+        } else {
+            SshFxpNameReply reply = new SshFxpNameReply(id);
+            reply.addFile(p, normalizedPath, getLongName(p), new FileAttributes());
+            return reply;
+        }
     }
 
     private Reply doProcessRmdir(SshFxpRmdirRequest request) throws IOException {