Repository: mina-sshd Updated Branches: refs/heads/master 3eefdb3f8 -> 2678bbfe6
[SSHD-548] Export some inner private classes as public static ones Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/2678bbfe Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/2678bbfe Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/2678bbfe Branch: refs/heads/master Commit: 2678bbfe6f685239ebb1b148a80b3086715f236f Parents: 3eefdb3 Author: Lyor Goldstein <[email protected]> Authored: Tue Aug 4 14:36:06 2015 +0300 Committer: Lyor Goldstein <[email protected]> Committed: Tue Aug 4 14:36:06 2015 +0300 ---------------------------------------------------------------------- .../sshd/client/channel/ChannelSubsystem.java | 12 + .../subsystem/sftp/AbstractSftpClient.java | 246 +------------------ .../sshd/client/subsystem/sftp/SftpCommand.java | 1 + .../subsystem/sftp/SftpDirEntryIterator.java | 157 ++++++++++++ .../subsystem/sftp/SftpDirectoryStream.java | 65 +++++ .../client/subsystem/sftp/SftpFileSystem.java | 25 +- .../subsystem/sftp/SftpFileSystemProvider.java | 219 +---------------- .../sftp/SftpInputStreamWithChannel.java | 127 ++++++++++ .../subsystem/sftp/SftpIterableDirEntry.java | 64 +++++ .../sftp/SftpOutputStreamWithChannel.java | 124 ++++++++++ .../client/subsystem/sftp/SftpPathIterator.java | 82 +++++++ .../sftp/SftpPosixFileAttributeView.java | 126 ++++++++++ .../subsystem/sftp/SftpPosixFileAttributes.java | 111 +++++++++ .../common/channel/ChannelRequestHandler.java | 1 + .../org/apache/sshd/common/channel/PtyMode.java | 1 - .../sshd/common/forward/TcpipClientChannel.java | 5 +- .../ConnectionServiceRequestHandler.java | 1 + .../apache/sshd/common/mac/BuiltinMacsTest.java | 1 - .../common/signature/BuiltinSignaturesTest.java | 1 - 19 files changed, 897 insertions(+), 472 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2678bbfe/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelSubsystem.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelSubsystem.java b/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelSubsystem.java index 583c937..b4d8c8f 100644 --- a/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelSubsystem.java +++ b/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelSubsystem.java @@ -35,10 +35,22 @@ public class ChannelSubsystem extends ChannelSession { private final String subsystem; + /** + * @param subsystem The subsystem name for the channel - never {@code null} or empty + */ public ChannelSubsystem(String subsystem) { this.subsystem = ValidateUtils.checkNotNullAndNotEmpty(subsystem, "Subsystem may not be null/empty"); } + /** + * The subsystem name + * + * @return The subsystem name for the channel - never {@code null} or empty + */ + public final String getSubsystem() { + return subsystem; + } + @Override protected void doOpen() throws IOException { log.debug("Send SSH_MSG_CHANNEL_REQUEST exec"); http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2678bbfe/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 db7afc5..28aae10 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 @@ -16,7 +16,6 @@ * specific language governing permissions and limitations * under the License. */ - package org.apache.sshd.client.subsystem.sftp; import java.io.IOException; @@ -27,7 +26,6 @@ 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; @@ -43,8 +41,6 @@ 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; @@ -373,7 +369,7 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements int id = buffer.getInt(); if (type == SSH_FXP_ATTRS) { return readAttributes(buffer); - } + } if (type == SSH_FXP_STATUS) { int substatus = buffer.getInt(); @@ -424,7 +420,7 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements } return name; } - + if (type == SSH_FXP_STATUS) { int substatus = buffer.getInt(); String msg = buffer.getString(); @@ -900,7 +896,7 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements if (log.isTraceEnabled()) { log.trace("checkDir(id={})[{}] ({})[{}]: {}", Integer.valueOf(id), Integer.valueOf(i), name, longName, attrs); } - + entries.add(new DirEntry(name, longName, attrs)); } return entries; @@ -1080,7 +1076,7 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements if (!isOpen()) { throw new IOException("readDir(" + path + ") client is closed"); } - return new DirEntryIterable(path); + return new SftpIterableDirEntry(this, path); } @Override @@ -1093,7 +1089,7 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements throw new IOException("read(" + path + ")[" + mode + "] size=" + bufferSize + ": client is closed"); } - return new SftpInputStreamWithChannel(bufferSize, path, mode); + return new SftpInputStreamWithChannel(this, bufferSize, path, mode); } @Override @@ -1106,236 +1102,6 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements 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; - - public DirEntryIterator() { - 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"); - } - } - } - - 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); - } - - @Override - public boolean isOpen() { - return (handle != null) && handle.isOpen(); - } - - @Override - public void write(int b) throws IOException { - bb[0] = (byte) b; - write(bb, 0, 1); - } - - @Override - public void write(byte[] b, int off, int len) throws IOException { - if (!isOpen()) { - throw new IOException("write(" + path + ")[len=" + len + "] stream is closed"); - } - - 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"); - } - - AbstractSftpClient.this.write(handle, offset, buffer, 0, index); - offset += index; - index = 0; - } - - @Override - public void close() throws IOException { - if (isOpen()) { - try { - try { - if (index > 0) { - flush(); - } - } finally { - handle.close(); - } - } 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]; - } - - return read; - } - - @Override - public int read(byte[] b, int off, int len) throws IOException { - if (!isOpen()) { - throw new IOException("read(" + path + ") stream closed"); - } - - 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; - } - 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; - } - } - } + return new SftpOutputStreamWithChannel(this, bufferSize, path, mode); } } http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2678bbfe/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 d132fe3..ca0d294 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 @@ -53,6 +53,7 @@ public class SftpCommand implements Channel { private final Map<String, CommandExecutor> commandsMap; private String cwdRemote; + @SuppressWarnings("synthetic-access") public SftpCommand(SftpClient client) { this.client = ValidateUtils.checkNotNull(client, "No client"); http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2678bbfe/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpDirEntryIterator.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpDirEntryIterator.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpDirEntryIterator.java new file mode 100644 index 0000000..b933f1f --- /dev/null +++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpDirEntryIterator.java @@ -0,0 +1,157 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sshd.client.subsystem.sftp; + +import java.io.IOException; +import java.nio.channels.Channel; +import java.util.Iterator; +import java.util.List; + +import org.apache.sshd.client.subsystem.sftp.SftpClient.CloseableHandle; +import org.apache.sshd.client.subsystem.sftp.SftpClient.DirEntry; +import org.apache.sshd.common.util.ValidateUtils; +import org.apache.sshd.common.util.logging.AbstractLoggingBean; + +/** + * Iterates over the available directory entries for a given path. <B>Note:</B> + * if the iteration is carried out until no more entries are available, then + * no need to close the iterator. Otherwise, it is recommended to close it so + * as to release the internal handle. + * + * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> + */ +public class SftpDirEntryIterator extends AbstractLoggingBean implements Iterator<DirEntry>, Channel { + private final SftpClient client; + private final String dirPath; + private CloseableHandle dirHandle; + private List<DirEntry> dirEntries; + private int index; + + /** + * @param client The {@link SftpClient} instance to use for the iteration + * @param path The remote directory path + */ + public SftpDirEntryIterator(SftpClient client, String path) { + this.client = ValidateUtils.checkNotNull(client, "No SFTP client instance"); + this.dirPath = path; + this.dirHandle = open(path); + this.dirEntries = load(dirHandle); + } + + /** + * The client instance + * + * @return {@link SftpClient} instance used to access the remote file + */ + public final SftpClient getClient() { + return client; + } + + /** + * The remotely accessed directory path + * + * @return Remote directory path + */ + public final String getPath() { + return dirPath; + } + + @Override + public boolean hasNext() { + return (dirEntries != null) && (index < dirEntries.size()); + } + + @Override + public DirEntry next() { + DirEntry entry = dirEntries.get(index++); + if (index >= dirEntries.size()) { + index = 0; + + try { + dirEntries = load(dirHandle); + } catch (RuntimeException e) { + dirEntries = null; + throw e; + } + } + + return entry; + } + + @Override + public boolean isOpen() { + return (dirHandle != null) && dirHandle.isOpen(); + } + + @Override + public void close() throws IOException { + if (isOpen()) { + if (log.isDebugEnabled()) { + log.debug("close(" + getPath() + ") handle=" + dirHandle); + } + dirHandle.close(); + } + } + + protected CloseableHandle open(String path) { + try { + CloseableHandle handle = client.openDir(path); + if (log.isDebugEnabled()) { + log.debug("open(" + path + ") handle=" + handle); + } + + return handle; + } catch (IOException e) { + if (log.isDebugEnabled()) { + log.debug("open(" + path + ") failed (" + e.getClass().getSimpleName() + ") to open dir: " + e.getMessage()); + } + throw new RuntimeException(e); + } + } + + protected List<DirEntry> load(CloseableHandle handle) { + try { + List<DirEntry> entries = client.readDir(handle); + if (entries == null) { + if (log.isTraceEnabled()) { + log.trace("load(" + getPath() + ") exhausted all entries"); + } + close(); + } + + return entries; + } catch (IOException e) { + try { + 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(" + getPath() + ") Iterator#remove() N/A"); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2678bbfe/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpDirectoryStream.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpDirectoryStream.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpDirectoryStream.java new file mode 100644 index 0000000..3217ecb --- /dev/null +++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpDirectoryStream.java @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sshd.client.subsystem.sftp; + +import java.io.IOException; +import java.nio.file.DirectoryStream; +import java.nio.file.Path; +import java.util.Iterator; + +/** + * Implements a remote {@link DirectoryStream} + * + * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> + */ +public class SftpDirectoryStream implements DirectoryStream<Path> { + private final SftpClient sftp; + private final Iterable<SftpClient.DirEntry> iter; + private final SftpPath p; + + /** + * @param path The remote {@link SftpPath} + * @throws IOException If failed to initialize the directory access handle + */ + public SftpDirectoryStream(SftpPath path) throws IOException { + SftpFileSystem fs = path.getFileSystem(); + p = path; + sftp = fs.getClient(); + iter = sftp.readDir(path.toString()); + } + + /** + * Client instance used to access the remote directory + * + * @return The {@link SftpClient} instance used to access the remote directory + */ + public final SftpClient getClient() { + return sftp; + } + + @Override + public Iterator<Path> iterator() { + return new SftpPathIterator(p, iter); + } + + @Override + public void close() throws IOException { + sftp.close(); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2678bbfe/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 444082c..576eda0 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 @@ -32,6 +32,7 @@ import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Queue; import java.util.Set; import java.util.concurrent.LinkedBlockingQueue; @@ -485,7 +486,10 @@ public class SftpFileSystem extends BaseFileSystem<SftpPath> { } } - protected static class DefaultUserPrincipalLookupService extends UserPrincipalLookupService { + public static class DefaultUserPrincipalLookupService extends UserPrincipalLookupService { + public DefaultUserPrincipalLookupService() { + super(); + } @Override public UserPrincipal lookupPrincipalByName(String name) throws IOException { @@ -498,19 +502,16 @@ public class SftpFileSystem extends BaseFileSystem<SftpPath> { } } - protected static class DefaultUserPrincipal implements UserPrincipal { + public static class DefaultUserPrincipal implements UserPrincipal { private final String name; public DefaultUserPrincipal(String name) { - if (name == null) { - throw new IllegalArgumentException("name is null"); - } - this.name = name; + this.name = ValidateUtils.checkNotNull(name, "name is null"); } @Override - public String getName() { + public final String getName() { return name; } @@ -523,26 +524,24 @@ public class SftpFileSystem extends BaseFileSystem<SftpPath> { return false; } DefaultUserPrincipal that = (DefaultUserPrincipal) o; - return name.equals(that.name); + return Objects.equals(this.getName(), that.getName()); } @Override public int hashCode() { - return name.hashCode(); + return Objects.hashCode(getName()); } @Override public String toString() { - return name; + return getName(); } } - protected static class DefaultGroupPrincipal extends DefaultUserPrincipal implements GroupPrincipal { + public static class DefaultGroupPrincipal extends DefaultUserPrincipal implements GroupPrincipal { public DefaultGroupPrincipal(String name) { super(name); } - } - } http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2678bbfe/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystemProvider.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystemProvider.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystemProvider.java index 87579c5..8b5eeab 100644 --- a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystemProvider.java +++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystemProvider.java @@ -60,9 +60,7 @@ import java.util.Collections; import java.util.EnumSet; import java.util.HashMap; import java.util.HashSet; -import java.util.Iterator; import java.util.Map; -import java.util.NoSuchElementException; import java.util.Set; import java.util.concurrent.TimeUnit; @@ -289,7 +287,7 @@ public class SftpFileSystemProvider extends FileSystemProvider { } else if (option == StandardOpenOption.SPARSE) { /* * As per the Javadoc: - * + * * The option is ignored when the file system does not * support the creation of sparse files */ @@ -309,7 +307,7 @@ public class SftpFileSystemProvider extends FileSystemProvider { @Override public DirectoryStream<Path> newDirectoryStream(Path dir, DirectoryStream.Filter<? super Path> filter) throws IOException { final SftpPath p = toSftpPath(dir); - return new PathDirectoryStream(p); + return new SftpDirectoryStream(p); } @Override @@ -576,7 +574,7 @@ public class SftpFileSystemProvider extends FileSystemProvider { @Override public <V extends FileAttributeView> V getFileAttributeView(final Path path, Class<V> type, final LinkOption... options) { if (isSupportedFileAttributeView(type)) { - return type.cast(new SftpPosixFileAttributeView(path, options)); + return type.cast(new SftpPosixFileAttributeView(this, path, options)); } else { throw new UnsupportedOperationException("getFileAttributeView(" + path + ") view not supported: " + type.getSimpleName()); } @@ -728,7 +726,7 @@ public class SftpFileSystemProvider extends FileSystemProvider { } } - private SftpPath toSftpPath(Path path) { + protected SftpPath toSftpPath(Path path) { ValidateUtils.checkNotNull(path, "No path provided"); if (!(path instanceof SftpPath)) { throw new ProviderMismatchException("Path is not SFTP: " + path); @@ -960,213 +958,4 @@ public class SftpFileSystemProvider extends FileSystemProvider { public static URI createFileSystemURI(String host, int port, String username, String password) { return URI.create(SftpConstants.SFTP_SUBSYSTEM_NAME + "://" + username + ":" + password + "@" + host + ":" + port + "/"); } - - private static class PathDirectoryStream implements DirectoryStream<Path> { - private final SftpFileSystem fs; - private final SftpClient sftp; - private final Iterable<SftpClient.DirEntry> iter; - private final SftpPath p; - - public PathDirectoryStream(SftpPath p) throws IOException { - this.p = p; - fs = p.getFileSystem(); - sftp = fs.getClient(); - iter = sftp.readDir(p.toString()); - } - - @Override - public Iterator<Path> iterator() { - return new PathIterator(); - } - - @Override - public void close() throws IOException { - sftp.close(); - } - - private class PathIterator implements Iterator<Path> { - @SuppressWarnings("synthetic-access") - private final Iterator<SftpClient.DirEntry> it = (iter == null) ? null : iter.iterator(); - private boolean dotIgnored; - private boolean dotdotIgnored; - private SftpClient.DirEntry curEntry = nextEntry(); - - @Override - public boolean hasNext() { - return curEntry != null; - } - - @Override - public Path next() { - if (curEntry == null) { - throw new NoSuchElementException("No next entry"); - } - - SftpClient.DirEntry entry = curEntry; - curEntry = nextEntry(); - return p.resolve(entry.filename); - } - - private SftpClient.DirEntry nextEntry() { - while ((it != null) && it.hasNext()) { - SftpClient.DirEntry entry = it.next(); - String name = entry.filename; - if (".".equals(name) && (!dotIgnored)) { - dotIgnored = true; - } else if ("..".equals(name) && (!dotdotIgnored)) { - dotdotIgnored = true; - } else { - return entry; - } - } - - return null; - } - - @Override - public void remove() { - throw new UnsupportedOperationException("newDirectoryStream(" + p + ") Iterator#remove() N/A"); - } - } - } - - private class SftpPosixFileAttributeView implements PosixFileAttributeView { - private final Path path; - private final LinkOption[] options; - - public SftpPosixFileAttributeView(Path path, LinkOption... options) { - this.path = path; - this.options = options; - } - - @Override - public String name() { - return "view"; - } - - @SuppressWarnings("synthetic-access") - @Override - public PosixFileAttributes readAttributes() throws IOException { - SftpPath p = toSftpPath(path); - SftpFileSystem fs = p.getFileSystem(); - final Attributes attributes; - try (SftpClient client = fs.getClient()) { - try { - if (IoUtils.followLinks(options)) { - attributes = client.stat(p.toString()); - } else { - attributes = client.lstat(p.toString()); - } - } catch (SftpException e) { - if (e.getStatus() == SftpConstants.SSH_FX_NO_SUCH_FILE) { - throw new NoSuchFileException(p.toString()); - } - throw e; - } - } - return new SftpPosixFileAttributes(attributes); - } - - @Override - public void setTimes(FileTime lastModifiedTime, FileTime lastAccessTime, FileTime createTime) throws IOException { - if (lastModifiedTime != null) { - setAttribute(path, "lastModifiedTime", lastModifiedTime, options); - } - if (lastAccessTime != null) { - setAttribute(path, "lastAccessTime", lastAccessTime, options); - } - if (createTime != null) { - setAttribute(path, "createTime", createTime, options); - } - } - - @Override - public void setPermissions(Set<PosixFilePermission> perms) throws IOException { - setAttribute(path, "permissions", perms, options); - } - - @Override - public void setGroup(GroupPrincipal group) throws IOException { - setAttribute(path, "group", group, options); - } - - @Override - public UserPrincipal getOwner() throws IOException { - return readAttributes().owner(); - } - - @Override - public void setOwner(UserPrincipal owner) throws IOException { - setAttribute(path, "owner", owner, options); - } - - private class SftpPosixFileAttributes implements PosixFileAttributes { - private final Attributes attributes; - - public SftpPosixFileAttributes(Attributes attributes) { - this.attributes = attributes; - } - - @Override - public UserPrincipal owner() { - return attributes.owner != null ? new SftpFileSystem.DefaultGroupPrincipal(attributes.owner) : null; - } - - @Override - public GroupPrincipal group() { - return attributes.group != null ? new SftpFileSystem.DefaultGroupPrincipal(attributes.group) : null; - } - - @Override - public Set<PosixFilePermission> permissions() { - return permissionsToAttributes(attributes.perms); - } - - @Override - public FileTime lastModifiedTime() { - return FileTime.from(attributes.mtime, TimeUnit.SECONDS); - } - - @Override - public FileTime lastAccessTime() { - return FileTime.from(attributes.atime, TimeUnit.SECONDS); - } - - @Override - public FileTime creationTime() { - return FileTime.from(attributes.ctime, TimeUnit.SECONDS); - } - - @Override - public boolean isRegularFile() { - return attributes.isRegularFile(); - } - - @Override - public boolean isDirectory() { - return attributes.isDirectory(); - } - - @Override - public boolean isSymbolicLink() { - return attributes.isSymbolicLink(); - } - - @Override - public boolean isOther() { - return attributes.isOther(); - } - - @Override - public long size() { - return attributes.size; - } - - @Override - public Object fileKey() { - // TODO - return null; - } - } - } } http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2678bbfe/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpInputStreamWithChannel.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpInputStreamWithChannel.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpInputStreamWithChannel.java new file mode 100644 index 0000000..530b2e1 --- /dev/null +++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpInputStreamWithChannel.java @@ -0,0 +1,127 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sshd.client.subsystem.sftp; + +import java.io.IOException; +import java.util.Collection; + +import org.apache.sshd.client.subsystem.sftp.SftpClient.CloseableHandle; +import org.apache.sshd.client.subsystem.sftp.SftpClient.OpenMode; +import org.apache.sshd.common.util.ValidateUtils; +import org.apache.sshd.common.util.io.InputStreamWithChannel; + +/** + * Implements an input stream for reading from a remote file + * + * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> + */ +public class SftpInputStreamWithChannel extends InputStreamWithChannel { + private final SftpClient client; + private final String path; + private byte[] bb; + private byte[] buffer; + private int index; + private int available; + private CloseableHandle handle; + private long offset; + + public SftpInputStreamWithChannel(SftpClient client, int bufferSize, String path, Collection<OpenMode> mode) throws IOException { + this.client = ValidateUtils.checkNotNull(client, "No SFTP client instance"); + this.path = path; + bb = new byte[1]; + buffer = new byte[bufferSize]; + handle = client.open(path, mode); + } + + /** + * The client instance + * + * @return {@link SftpClient} instance used to access the remote file + */ + public final SftpClient getClient() { + return client; + } + + /** + * The remotely accessed file path + * + * @return Remote file path + */ + public final String getPath() { + return path; + } + + @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]; + } + + return read; + } + + @Override + public int read(byte[] b, int off, int len) throws IOException { + if (!isOpen()) { + throw new IOException("read(" + getPath() + ") stream closed"); + } + + int idx = off; + while (len > 0) { + if (index >= available) { + available = client.read(handle, offset, buffer, 0, buffer.length); + if (available < 0) { + if (idx == off) { + return -1; + } else { + break; + } + } + 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; + } + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2678bbfe/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpIterableDirEntry.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpIterableDirEntry.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpIterableDirEntry.java new file mode 100644 index 0000000..7300da7 --- /dev/null +++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpIterableDirEntry.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sshd.client.subsystem.sftp; + +import org.apache.sshd.client.subsystem.sftp.SftpClient.DirEntry; + +/** + * Provides an {@link Iterable} implementation of the {@link DirEntry}-ies + * for a remote directory + * + * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> + */ +public class SftpIterableDirEntry implements Iterable<DirEntry> { + private final SftpClient client; + private final String path; + + /** + * @param client The {@link SftpClient} instance to use for the iteration + * @param path The remote directory path + */ + public SftpIterableDirEntry(SftpClient client, String path) { + this.client = client; + this.path = path; + } + + /** + * The client instance + * + * @return {@link SftpClient} instance used to access the remote file + */ + public final SftpClient getClient() { + return client; + } + + /** + * The remotely accessed directory path + * + * @return Remote directory path + */ + public final String getPath() { + return path; + } + + @Override + public SftpDirEntryIterator iterator() { + return new SftpDirEntryIterator(getClient(), getPath()); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2678bbfe/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpOutputStreamWithChannel.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpOutputStreamWithChannel.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpOutputStreamWithChannel.java new file mode 100644 index 0000000..4cc6845 --- /dev/null +++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpOutputStreamWithChannel.java @@ -0,0 +1,124 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sshd.client.subsystem.sftp; + +import java.io.IOException; +import java.util.Collection; + +import org.apache.sshd.client.subsystem.sftp.SftpClient.CloseableHandle; +import org.apache.sshd.client.subsystem.sftp.SftpClient.OpenMode; +import org.apache.sshd.common.util.ValidateUtils; +import org.apache.sshd.common.util.io.OutputStreamWithChannel; + +/** + * Implements an output stream for a given remote file + * + * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> + */ +public class SftpOutputStreamWithChannel extends OutputStreamWithChannel { + private final SftpClient client; + private final String path; + private final byte[] bb = new byte[1]; + private final byte[] buffer; + private int index; + private CloseableHandle handle; + private long offset; + + public SftpOutputStreamWithChannel(SftpClient client, int bufferSize, String path, Collection<OpenMode> mode) throws IOException { + this.client = ValidateUtils.checkNotNull(client, "No SFTP client instance"); + this.path = path; + buffer = new byte[bufferSize]; + handle = client.open(path, mode); + } + + /** + * The client instance + * + * @return {@link SftpClient} instance used to access the remote file + */ + public final SftpClient getClient() { + return client; + } + + /** + * The remotely accessed file path + * + * @return Remote file path + */ + public final String getPath() { + return path; + } + + @Override + public boolean isOpen() { + return (handle != null) && handle.isOpen(); + } + + @Override + public void write(int b) throws IOException { + bb[0] = (byte) b; + write(bb, 0, 1); + } + + @Override + public void write(byte[] b, int off, int len) throws IOException { + if (!isOpen()) { + throw new IOException("write(" + getPath() + ")[len=" + len + "] stream is closed"); + } + + 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(" + getPath() + ") stream is closed"); + } + + client.write(handle, offset, buffer, 0, index); + offset += index; + index = 0; + } + + @Override + public void close() throws IOException { + if (isOpen()) { + try { + try { + if (index > 0) { + flush(); + } + } finally { + handle.close(); + } + } finally { + handle = null; + } + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2678bbfe/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpPathIterator.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpPathIterator.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpPathIterator.java new file mode 100644 index 0000000..ad6bb71 --- /dev/null +++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpPathIterator.java @@ -0,0 +1,82 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.sshd.client.subsystem.sftp; + +import java.nio.file.Path; +import java.util.Iterator; +import java.util.NoSuchElementException; + +/** + * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> + */ +public class SftpPathIterator implements Iterator<Path> { + private final SftpPath p; + private final Iterator<? extends SftpClient.DirEntry> it; + private boolean dotIgnored; + private boolean dotdotIgnored; + private SftpClient.DirEntry curEntry; + + public SftpPathIterator(SftpPath path, Iterable<? extends SftpClient.DirEntry> iter) { + this(path, (iter == null) ? null : iter.iterator()); + } + + public SftpPathIterator(SftpPath path, Iterator<? extends SftpClient.DirEntry> iter) { + p = path; + it = iter; + curEntry = nextEntry(); + } + + @Override + public boolean hasNext() { + return curEntry != null; + } + + @Override + public Path next() { + if (curEntry == null) { + throw new NoSuchElementException("No next entry"); + } + + SftpClient.DirEntry entry = curEntry; + curEntry = nextEntry(); + return p.resolve(entry.filename); + } + + private SftpClient.DirEntry nextEntry() { + while ((it != null) && it.hasNext()) { + SftpClient.DirEntry entry = it.next(); + String name = entry.filename; + if (".".equals(name) && (!dotIgnored)) { + dotIgnored = true; + } else if ("..".equals(name) && (!dotdotIgnored)) { + dotdotIgnored = true; + } else { + return entry; + } + } + + return null; + } + + @Override + public void remove() { + throw new UnsupportedOperationException("newDirectoryStream(" + p + ") Iterator#remove() N/A"); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2678bbfe/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpPosixFileAttributeView.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpPosixFileAttributeView.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpPosixFileAttributeView.java new file mode 100644 index 0000000..6c7cef4 --- /dev/null +++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpPosixFileAttributeView.java @@ -0,0 +1,126 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sshd.client.subsystem.sftp; + +import java.io.IOException; +import java.nio.file.LinkOption; +import java.nio.file.NoSuchFileException; +import java.nio.file.Path; +import java.nio.file.attribute.FileTime; +import java.nio.file.attribute.GroupPrincipal; +import java.nio.file.attribute.PosixFileAttributeView; +import java.nio.file.attribute.PosixFileAttributes; +import java.nio.file.attribute.PosixFilePermission; +import java.nio.file.attribute.UserPrincipal; +import java.util.Set; + +import org.apache.sshd.client.subsystem.sftp.SftpClient.Attributes; +import org.apache.sshd.common.subsystem.sftp.SftpConstants; +import org.apache.sshd.common.util.ValidateUtils; +import org.apache.sshd.common.util.io.IoUtils; + +/** + * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> + */ +public class SftpPosixFileAttributeView implements PosixFileAttributeView { + private final SftpFileSystemProvider provider; + private final Path path; + private final LinkOption[] options; + + public SftpPosixFileAttributeView(SftpFileSystemProvider provider, Path path, LinkOption... options) { + this.provider = ValidateUtils.checkNotNull(provider, "No file system provider instance"); + this.path = path; + this.options = options; + } + + @Override + public String name() { + return "view"; + } + + /** + * @return The underlying {@link SftpFileSystemProvider} used to + * provide the view functionality + */ + public final SftpFileSystemProvider provider() { + return provider; + } + + /** + * @return The referenced view {@link Path} + */ + public final Path getPath() { + return path; + } + + @Override + public PosixFileAttributes readAttributes() throws IOException { + SftpPath p = provider.toSftpPath(path); + SftpFileSystem fs = p.getFileSystem(); + final Attributes attributes; + try (SftpClient client = fs.getClient()) { + try { + if (IoUtils.followLinks(options)) { + attributes = client.stat(p.toString()); + } else { + attributes = client.lstat(p.toString()); + } + } catch (SftpException e) { + if (e.getStatus() == SftpConstants.SSH_FX_NO_SUCH_FILE) { + throw new NoSuchFileException(p.toString()); + } + throw e; + } + } + return new SftpPosixFileAttributes(path, attributes); + } + + @Override + public void setTimes(FileTime lastModifiedTime, FileTime lastAccessTime, FileTime createTime) throws IOException { + if (lastModifiedTime != null) { + provider.setAttribute(path, "lastModifiedTime", lastModifiedTime, options); + } + if (lastAccessTime != null) { + provider.setAttribute(path, "lastAccessTime", lastAccessTime, options); + } + if (createTime != null) { + provider.setAttribute(path, "createTime", createTime, options); + } + } + + @Override + public void setPermissions(Set<PosixFilePermission> perms) throws IOException { + provider.setAttribute(path, "permissions", perms, options); + } + + @Override + public void setGroup(GroupPrincipal group) throws IOException { + provider.setAttribute(path, "group", group, options); + } + + @Override + public UserPrincipal getOwner() throws IOException { + return readAttributes().owner(); + } + + @Override + public void setOwner(UserPrincipal owner) throws IOException { + provider.setAttribute(path, "owner", owner, options); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2678bbfe/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpPosixFileAttributes.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpPosixFileAttributes.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpPosixFileAttributes.java new file mode 100644 index 0000000..9790b01 --- /dev/null +++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpPosixFileAttributes.java @@ -0,0 +1,111 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sshd.client.subsystem.sftp; + +import java.nio.file.Path; +import java.nio.file.attribute.FileTime; +import java.nio.file.attribute.GroupPrincipal; +import java.nio.file.attribute.PosixFileAttributes; +import java.nio.file.attribute.PosixFilePermission; +import java.nio.file.attribute.UserPrincipal; +import java.util.Set; +import java.util.concurrent.TimeUnit; + +import org.apache.sshd.client.subsystem.sftp.SftpClient.Attributes; + +/** + * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> + */ +public class SftpPosixFileAttributes implements PosixFileAttributes { + private final Path path; + private final Attributes attributes; + + public SftpPosixFileAttributes(Path path, Attributes attributes) { + this.path = path; + this.attributes = attributes; + } + + /** + * @return The referenced attributes file {@link Path} + */ + public final Path getPath() { + return path; + } + + @Override + public UserPrincipal owner() { + return attributes.owner != null ? new SftpFileSystem.DefaultGroupPrincipal(attributes.owner) : null; + } + + @Override + public GroupPrincipal group() { + return attributes.group != null ? new SftpFileSystem.DefaultGroupPrincipal(attributes.group) : null; + } + + @Override + public Set<PosixFilePermission> permissions() { + return SftpFileSystemProvider.permissionsToAttributes(attributes.perms); + } + + @Override + public FileTime lastModifiedTime() { + return FileTime.from(attributes.mtime, TimeUnit.SECONDS); + } + + @Override + public FileTime lastAccessTime() { + return FileTime.from(attributes.atime, TimeUnit.SECONDS); + } + + @Override + public FileTime creationTime() { + return FileTime.from(attributes.ctime, TimeUnit.SECONDS); + } + + @Override + public boolean isRegularFile() { + return attributes.isRegularFile(); + } + + @Override + public boolean isDirectory() { + return attributes.isDirectory(); + } + + @Override + public boolean isSymbolicLink() { + return attributes.isSymbolicLink(); + } + + @Override + public boolean isOther() { + return attributes.isOther(); + } + + @Override + public long size() { + return attributes.size; + } + + @Override + public Object fileKey() { + // TODO consider implementing this + return null; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2678bbfe/sshd-core/src/main/java/org/apache/sshd/common/channel/ChannelRequestHandler.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/channel/ChannelRequestHandler.java b/sshd-core/src/main/java/org/apache/sshd/common/channel/ChannelRequestHandler.java index e7d5e65..8210c23 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/channel/ChannelRequestHandler.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/channel/ChannelRequestHandler.java @@ -36,6 +36,7 @@ public interface ChannelRequestHandler extends RequestHandler<Channel> { } }; + @Override Result process(Channel channel, String request, boolean wantReply, Buffer buffer) throws Exception; } http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2678bbfe/sshd-core/src/main/java/org/apache/sshd/common/channel/PtyMode.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/channel/PtyMode.java b/sshd-core/src/main/java/org/apache/sshd/common/channel/PtyMode.java index b0ec6db..fd81ee0 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/channel/PtyMode.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/channel/PtyMode.java @@ -19,7 +19,6 @@ package org.apache.sshd.common.channel; import java.util.Collections; -import java.util.HashMap; import java.util.Map; /** http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2678bbfe/sshd-core/src/main/java/org/apache/sshd/common/forward/TcpipClientChannel.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/forward/TcpipClientChannel.java b/sshd-core/src/main/java/org/apache/sshd/common/forward/TcpipClientChannel.java index 8d8a729..2cc657f 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/forward/TcpipClientChannel.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/forward/TcpipClientChannel.java @@ -40,7 +40,10 @@ import org.apache.sshd.common.util.buffer.ByteArrayBuffer; */ public class TcpipClientChannel extends AbstractClientChannel { - public enum Type { + /** + * Type of channel being created + */ + public static enum Type { Direct, Forwarded } http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2678bbfe/sshd-core/src/main/java/org/apache/sshd/common/session/ConnectionServiceRequestHandler.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/ConnectionServiceRequestHandler.java b/sshd-core/src/main/java/org/apache/sshd/common/session/ConnectionServiceRequestHandler.java index 9749345..39ef956 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/session/ConnectionServiceRequestHandler.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/session/ConnectionServiceRequestHandler.java @@ -31,6 +31,7 @@ public interface ConnectionServiceRequestHandler extends RequestHandler<Connecti // required because of generics issues Transformer<ConnectionServiceRequestHandler, RequestHandler<ConnectionService>> SVC2HNDLR = Transformer.Utils.identity(); + @Override Result process(ConnectionService service, String request, boolean wantReply, Buffer buffer) throws Exception; } http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2678bbfe/sshd-core/src/test/java/org/apache/sshd/common/mac/BuiltinMacsTest.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/test/java/org/apache/sshd/common/mac/BuiltinMacsTest.java b/sshd-core/src/test/java/org/apache/sshd/common/mac/BuiltinMacsTest.java index b2933e9..9c8fbc4 100644 --- a/sshd-core/src/test/java/org/apache/sshd/common/mac/BuiltinMacsTest.java +++ b/sshd-core/src/test/java/org/apache/sshd/common/mac/BuiltinMacsTest.java @@ -28,7 +28,6 @@ import java.util.List; import java.util.Random; import java.util.Set; -import org.apache.sshd.common.NamedFactory; import org.apache.sshd.common.NamedResource; import org.apache.sshd.common.mac.BuiltinMacs.ParseResult; import org.apache.sshd.common.util.GenericUtils; http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/2678bbfe/sshd-core/src/test/java/org/apache/sshd/common/signature/BuiltinSignaturesTest.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/test/java/org/apache/sshd/common/signature/BuiltinSignaturesTest.java b/sshd-core/src/test/java/org/apache/sshd/common/signature/BuiltinSignaturesTest.java index 7592b93..b2b89a1 100644 --- a/sshd-core/src/test/java/org/apache/sshd/common/signature/BuiltinSignaturesTest.java +++ b/sshd-core/src/test/java/org/apache/sshd/common/signature/BuiltinSignaturesTest.java @@ -25,7 +25,6 @@ import java.util.Collections; import java.util.List; import java.util.Random; -import org.apache.sshd.common.NamedFactory; import org.apache.sshd.common.NamedResource; import org.apache.sshd.common.signature.BuiltinSignatures.ParseResult; import org.apache.sshd.common.util.GenericUtils;
