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/09/06 16:03:24 UTC
[14/51] [abbrv] mina-sshd git commit: [SSHD-842] Split common
utilities code from sshd-core into sshd-common (new artifact)
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/util/io/DirectoryScanner.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/io/DirectoryScanner.java b/sshd-core/src/main/java/org/apache/sshd/common/util/io/DirectoryScanner.java
deleted file mode 100644
index 8b4e9ba..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/io/DirectoryScanner.java
+++ /dev/null
@@ -1,380 +0,0 @@
-/*
- * 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.common.util.io;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.sshd.common.util.GenericUtils;
-import org.apache.sshd.common.util.SelectorUtils;
-
-/**
- * <p>Class for scanning a directory for files/directories which match certain
- * criteria.</p>
- *
- * <p>These criteria consist of selectors and patterns which have been specified.
- * With the selectors you can select which files you want to have included.
- * Files which are not selected are excluded. With patterns you can include
- * or exclude files based on their filename.</p>
- *
- * <p>The idea is simple. A given directory is recursively scanned for all files
- * and directories. Each file/directory is matched against a set of selectors,
- * including special support for matching against filenames with include and
- * and exclude patterns. Only files/directories which match at least one
- * pattern of the include pattern list or other file selector, and don't match
- * any pattern of the exclude pattern list or fail to match against a required
- * selector will be placed in the list of files/directories found.</p>
- *
- * <p>When no list of include patterns is supplied, "**" will be used, which
- * means that everything will be matched. When no list of exclude patterns is
- * supplied, an empty list is used, such that nothing will be excluded. When
- * no selectors are supplied, none are applied.</p>
- *
- * <p>The filename pattern matching is done as follows:
- * The name to be matched is split up in path segments. A path segment is the
- * name of a directory or file, which is bounded by
- * <code>File.separator</code> ('/' under UNIX, '\' under Windows).
- * For example, "abc/def/ghi/xyz.java" is split up in the segments "abc",
- * "def","ghi" and "xyz.java".
- * The same is done for the pattern against which should be matched.</p>
- *
- * <p>The segments of the name and the pattern are then matched against each
- * other. When '**' is used for a path segment in the pattern, it matches
- * zero or more path segments of the name.</p>
- *
- * <p>There is a special case regarding the use of <code>File.separator</code>s
- * at the beginning of the pattern and the string to match:<br>
- * When a pattern starts with a <code>File.separator</code>, the string
- * to match must also start with a <code>File.separator</code>.
- * When a pattern does not start with a <code>File.separator</code>, the
- * string to match may not start with a <code>File.separator</code>.
- * When one of these rules is not obeyed, the string will not
- * match.</p>
- *
- * <p>When a name path segment is matched against a pattern path segment, the
- * following special characters can be used:<br>
- * '*' matches zero or more characters<br>
- * '?' matches one character.</p>
- *
- * <p>Examples:
- * <br>
- * <code>"**\*.class"</code> matches all <code>.class</code> files/dirs in a directory tree.
- * <br>
- * <code>"test\a??.java"</code> matches all files/dirs which start with an 'a', then two
- * more characters and then <code>".java"</code>, in a directory called test.
- * <br>
- * <code>"**"</code> matches everything in a directory tree.
- * <br>
- * <code>"**\test\**\XYZ*"</code> matches all files/dirs which start with <code>"XYZ"</code> and where
- * there is a parent directory called test (e.g. <code>"abc\test\def\ghi\XYZ123"</code>).
- * </p>
- *
- * <p>Case sensitivity may be turned off if necessary. By default, it is
- * turned on.</p>
- *
- * <p>Example of usage:</p>
- * <pre>
- * String[] includes = {"**\\*.class"};
- * String[] excludes = {"modules\\*\\**"};
- * ds.setIncludes(includes);
- * ds.setExcludes(excludes);
- * ds.setBasedir(new File("test"));
- * ds.setCaseSensitive(true);
- * ds.scan();
- *
- * System.out.println("FILES:");
- * String[] files = ds.getIncludedFiles();
- * for (int i = 0; i < files.length; i++) {
- * System.out.println(files[i]);
- * }
- * </pre>
- * <p>This will scan a directory called test for .class files, but excludes all
- * files in all proper subdirectories of a directory called "modules".</p>
- *
- * @author Arnout J. Kuiper
- * <a href="mailto:ajkuiper@wxs.nl">ajkuiper@wxs.nl</a>
- * @author Magesh Umasankar
- * @author <a href="mailto:bruce@callenish.com">Bruce Atherton</a>
- * @author <a href="mailto:levylambert@tiscali-dsl.de">Antoine Levy-Lambert</a>
- */
-public class DirectoryScanner {
-
- /**
- * The base directory to be scanned.
- */
- protected File basedir;
-
- /**
- * The patterns for the files to be included.
- */
- protected String[] includes;
-
- /**
- * The files which matched at least one include and no excludes
- * and were selected.
- */
- protected List<String> filesIncluded;
-
- /**
- * Whether or not the file system should be treated as a case sensitive
- * one.
- */
- protected boolean isCaseSensitive = true;
-
- public DirectoryScanner() {
- super();
- }
-
- public DirectoryScanner(String basedir, String... includes) {
- setBasedir(basedir);
- setIncludes(includes);
- }
-
- /**
- * Sets the base directory to be scanned. This is the directory which is
- * scanned recursively. All '/' and '\' characters are replaced by
- * <code>File.separatorChar</code>, so the separator used need not match
- * <code>File.separatorChar</code>.
- *
- * @param basedir The base directory to scan.
- * Must not be {@code null}.
- */
- public void setBasedir(String basedir) {
- setBasedir(new File(basedir.replace('/', File.separatorChar).replace('\\', File.separatorChar)));
- }
-
- /**
- * Sets the base directory to be scanned. This is the directory which is
- * scanned recursively.
- *
- * @param basedir The base directory for scanning.
- * Should not be {@code null}.
- */
- public void setBasedir(File basedir) {
- this.basedir = basedir;
- }
-
- /**
- * Returns the base directory to be scanned.
- * This is the directory which is scanned recursively.
- *
- * @return the base directory to be scanned
- */
- public File getBasedir() {
- return basedir;
- }
-
- /**
- * <p>Sets the list of include patterns to use. All '/' and '\' characters
- * are replaced by <code>File.separatorChar</code>, so the separator used
- * need not match <code>File.separatorChar</code>.</p>
- *
- * <p>When a pattern ends with a '/' or '\', "**" is appended.</p>
- *
- * @param includes A list of include patterns.
- * May be {@code null}, indicating that all files
- * should be included. If a non-{@code null}
- * list is given, all elements must be
- * non-{@code null}.
- */
- public void setIncludes(String[] includes) {
- if (includes == null) {
- this.includes = null;
- } else {
- this.includes = new String[includes.length];
- for (int i = 0; i < includes.length; i++) {
- this.includes[i] = normalizePattern(includes[i]);
- }
- }
- }
-
- /**
- * Scans the base directory for files which match at least one include
- * pattern and don't match any exclude patterns. If there are selectors
- * then the files must pass muster there, as well.
- *
- * @return the matching files
- * @throws IllegalStateException if the base directory was set
- * incorrectly (i.e. if it is {@code null}, doesn't exist,
- * or isn't a directory).
- */
- public String[] scan() throws IllegalStateException {
- if (basedir == null) {
- throw new IllegalStateException("No basedir set");
- }
- if (!basedir.exists()) {
- throw new IllegalStateException("basedir " + basedir
- + " does not exist");
- }
- if (!basedir.isDirectory()) {
- throw new IllegalStateException("basedir " + basedir
- + " is not a directory");
- }
- if (includes == null || includes.length == 0) {
- throw new IllegalStateException("No includes set ");
- }
-
- filesIncluded = new ArrayList<>();
-
- scandir(basedir, "");
-
- return getIncludedFiles();
- }
-
- /**
- * Scans the given directory for files and directories. Found files and
- * directories are placed in their respective collections, based on the
- * matching of includes, excludes, and the selectors. When a directory
- * is found, it is scanned recursively.
- *
- * @param dir The directory to scan. Must not be {@code null}.
- * @param vpath The path relative to the base directory (needed to
- * prevent problems with an absolute path when using
- * dir). Must not be {@code null}.
- */
- protected void scandir(File dir, String vpath) {
- String[] newfiles = dir.list();
- if (GenericUtils.isEmpty(newfiles)) {
- newfiles = GenericUtils.EMPTY_STRING_ARRAY;
- }
-
- for (String newfile : newfiles) {
- String name = vpath + newfile;
- File file = new File(dir, newfile);
- if (file.isDirectory()) {
- if (isIncluded(name)) {
- filesIncluded.add(name);
- scandir(file, name + File.separator);
- } else if (couldHoldIncluded(name)) {
- scandir(file, name + File.separator);
- }
- } else if (file.isFile()) {
- if (isIncluded(name)) {
- filesIncluded.add(name);
- }
- }
- }
- }
-
- /**
- * Returns the names of the files which matched at least one of the
- * include patterns and none of the exclude patterns.
- * The names are relative to the base directory.
- *
- * @return the names of the files which matched at least one of the
- * include patterns and none of the exclude patterns.
- */
- public String[] getIncludedFiles() {
- String[] files = new String[filesIncluded.size()];
- return filesIncluded.toArray(files);
- }
-
- /**
- * Tests whether or not a name matches against at least one include
- * pattern.
- *
- * @param name The name to match. Must not be {@code null}.
- * @return <code>true</code> when the name matches against at least one
- * include pattern, or <code>false</code> otherwise.
- */
- protected boolean isIncluded(String name) {
- for (String include : includes) {
- if (SelectorUtils.matchPath(include, name, isCaseSensitive)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Tests whether or not a name matches the start of at least one include
- * pattern.
- *
- * @param name The name to match. Must not be {@code null}.
- * @return <code>true</code> when the name matches against the start of at
- * least one include pattern, or <code>false</code> otherwise.
- */
- protected boolean couldHoldIncluded(String name) {
- for (String include : includes) {
- if (SelectorUtils.matchPatternStart(include, name, isCaseSensitive)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Normalizes the pattern, e.g. converts forward and backward slashes to the platform-specific file separator.
- *
- * @param pattern The pattern to normalize, must not be {@code null}.
- * @return The normalized pattern, never {@code null}.
- */
- private String normalizePattern(String pattern) {
- pattern = pattern.trim();
-
- if (pattern.startsWith(SelectorUtils.REGEX_HANDLER_PREFIX)) {
- if (File.separatorChar == '\\') {
- pattern = replace(pattern, "/", "\\\\", -1);
- } else {
- pattern = replace(pattern, "\\\\", "/", -1);
- }
- } else {
- pattern = pattern.replace(File.separatorChar == '/' ? '\\' : '/', File.separatorChar);
-
- if (pattern.endsWith(File.separator)) {
- pattern += "**";
- }
- }
-
- return pattern;
- }
-
- /**
- * <p>Replace a String with another String inside a larger String,
- * for the first <code>max</code> values of the search String.</p>
- *
- * <p>A {@code null} reference passed to this method is a no-op.</p>
- *
- * @param text text to search and replace in
- * @param repl String to search for
- * @param with String to replace with
- * @param max maximum number of values to replace, or <code>-1</code> if no maximum
- * @return the text with any replacements processed
- */
- @SuppressWarnings("PMD.AssignmentInOperand")
- public static String replace(String text, String repl, String with, int max) {
- if ((text == null) || (repl == null) || (with == null) || (repl.length() == 0)) {
- return text;
- }
-
- StringBuilder buf = new StringBuilder(text.length());
- int start = 0;
- for (int end = text.indexOf(repl, start); end != -1; end = text.indexOf(repl, start)) {
- buf.append(text.substring(start, end)).append(with);
- start = end + repl.length();
-
- if (--max == 0) {
- break;
- }
- }
- buf.append(text.substring(start));
- return buf.toString();
- }
-}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/util/io/EmptyInputStream.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/io/EmptyInputStream.java b/sshd-core/src/main/java/org/apache/sshd/common/util/io/EmptyInputStream.java
deleted file mode 100644
index 8a1a68d..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/io/EmptyInputStream.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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.common.util.io;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * A {@code /dev/null} implementation - always open
- *
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public class EmptyInputStream extends InputStream {
- public static final EmptyInputStream DEV_NULL = new EmptyInputStream();
-
- public EmptyInputStream() {
- super();
- }
-
- @Override
- public int read() throws IOException {
- return -1;
- }
-
- @Override
- public int read(byte[] b, int off, int len) throws IOException {
- return -1;
- }
-
- @Override
- public long skip(long n) throws IOException {
- return 0L;
- }
-
- @Override
- public int available() throws IOException {
- return 0;
- }
-
- @Override
- public synchronized void mark(int readlimit) {
- throw new UnsupportedOperationException("mark(" + readlimit + ") called despite the fact that markSupported=" + markSupported());
- }
-
- @Override
- public synchronized void reset() throws IOException {
- // ignored
- }
-}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/util/io/FileInfoExtractor.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/io/FileInfoExtractor.java b/sshd-core/src/main/java/org/apache/sshd/common/util/io/FileInfoExtractor.java
deleted file mode 100644
index feafd18..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/io/FileInfoExtractor.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * 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.common.util.io;
-
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.LinkOption;
-import java.nio.file.Path;
-import java.nio.file.attribute.FileTime;
-import java.nio.file.attribute.PosixFilePermission;
-import java.util.Set;
-
-/**
- * @param <T> Type of information being extracted
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-@FunctionalInterface
-public interface FileInfoExtractor<T> {
-
- FileInfoExtractor<Boolean> EXISTS = Files::exists;
-
- FileInfoExtractor<Boolean> ISDIR = Files::isDirectory;
-
- FileInfoExtractor<Boolean> ISREG = Files::isRegularFile;
-
- FileInfoExtractor<Boolean> ISSYMLINK = (file, options) -> Files.isSymbolicLink(file);
-
- FileInfoExtractor<Long> SIZE = (file, options) -> Files.size(file);
-
- FileInfoExtractor<Set<PosixFilePermission>> PERMISSIONS = IoUtils::getPermissions;
-
- FileInfoExtractor<FileTime> LASTMODIFIED = Files::getLastModifiedTime;
-
- T infoOf(Path file, LinkOption... options) throws IOException;
-
-}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/util/io/InputStreamWithChannel.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/io/InputStreamWithChannel.java b/sshd-core/src/main/java/org/apache/sshd/common/util/io/InputStreamWithChannel.java
deleted file mode 100644
index d847079..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/io/InputStreamWithChannel.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.common.util.io;
-
-import java.io.InputStream;
-import java.nio.channels.Channel;
-
-/**
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public abstract class InputStreamWithChannel extends InputStream implements Channel {
- protected InputStreamWithChannel() {
- super();
- }
-}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/util/io/IoUtils.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/io/IoUtils.java b/sshd-core/src/main/java/org/apache/sshd/common/util/io/IoUtils.java
deleted file mode 100644
index 10aa59a..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/io/IoUtils.java
+++ /dev/null
@@ -1,556 +0,0 @@
-/*
- * 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.common.util.io;
-
-import java.io.BufferedReader;
-import java.io.ByteArrayOutputStream;
-import java.io.Closeable;
-import java.io.EOFException;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.Reader;
-import java.net.URL;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.CopyOption;
-import java.nio.file.FileSystem;
-import java.nio.file.Files;
-import java.nio.file.LinkOption;
-import java.nio.file.OpenOption;
-import java.nio.file.Path;
-import java.nio.file.StandardOpenOption;
-import java.nio.file.attribute.FileAttribute;
-import java.nio.file.attribute.PosixFilePermission;
-import java.nio.file.attribute.UserPrincipal;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-
-import org.apache.sshd.common.util.GenericUtils;
-import org.apache.sshd.common.util.OsUtils;
-
-/**
- * TODO Add javadoc
- *
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public final class IoUtils {
-
- public static final OpenOption[] EMPTY_OPEN_OPTIONS = new OpenOption[0];
- public static final CopyOption[] EMPTY_COPY_OPTIONS = new CopyOption[0];
- public static final LinkOption[] EMPTY_LINK_OPTIONS = new LinkOption[0];
- public static final FileAttribute<?>[] EMPTY_FILE_ATTRIBUTES = new FileAttribute<?>[0];
-
- public static final List<String> WINDOWS_EXECUTABLE_EXTENSIONS = Collections.unmodifiableList(Arrays.asList(".bat", ".exe", ".cmd"));
-
- /**
- * Size of preferred work buffer when reading / writing data to / from streams
- */
- public static final int DEFAULT_COPY_SIZE = 8192;
-
- /**
- * The local O/S line separator
- */
- public static final String EOL = System.lineSeparator();
-
- /**
- * A {@link Set} of {@link StandardOpenOption}-s that indicate an intent
- * to create/modify a file
- */
- public static final Set<StandardOpenOption> WRITEABLE_OPEN_OPTIONS =
- Collections.unmodifiableSet(
- EnumSet.of(
- StandardOpenOption.APPEND, StandardOpenOption.CREATE,
- StandardOpenOption.CREATE_NEW, StandardOpenOption.DELETE_ON_CLOSE,
- StandardOpenOption.DSYNC, StandardOpenOption.SYNC,
- StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE));
-
- private static final byte[] EOL_BYTES = EOL.getBytes(StandardCharsets.UTF_8);
-
- private static final LinkOption[] NO_FOLLOW_OPTIONS = new LinkOption[]{LinkOption.NOFOLLOW_LINKS};
-
- /**
- * Private Constructor
- */
- private IoUtils() {
- throw new UnsupportedOperationException("No instance allowed");
- }
-
- /**
- * @return The local platform line separator bytes as UTF-8. <B>Note:</B>
- * each call returns a <U>new</U> instance in order to avoid inadvertent
- * changes in shared objects
- * @see #EOL
- */
- public static byte[] getEOLBytes() {
- return EOL_BYTES.clone();
- }
-
- public static LinkOption[] getLinkOptions(boolean followLinks) {
- if (followLinks) {
- return EMPTY_LINK_OPTIONS;
- } else { // return a clone that modifications to the array will not affect others
- return NO_FOLLOW_OPTIONS.clone();
- }
- }
-
- public static long copy(InputStream source, OutputStream sink) throws IOException {
- return copy(source, sink, DEFAULT_COPY_SIZE);
- }
-
- public static long copy(InputStream source, OutputStream sink, int bufferSize) throws IOException {
- long nread = 0L;
- byte[] buf = new byte[bufferSize];
- for (int n = source.read(buf); n > 0; n = source.read(buf)) {
- sink.write(buf, 0, n);
- nread += n;
- }
-
- return nread;
- }
-
- /**
- * Closes a bunch of resources suppressing any {@link IOException}s their
- * {@link Closeable#close()} method may have thrown
- *
- * @param closeables The {@link Closeable}s to close
- * @return The <U>first</U> {@link IOException} that occurred during closing
- * of a resource - if more than one exception occurred, they are added as
- * suppressed exceptions to the first one
- * @see Throwable#getSuppressed()
- */
- @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
- public static IOException closeQuietly(Closeable... closeables) {
- IOException err = null;
- for (Closeable c : closeables) {
- try {
- if (c != null) {
- c.close();
- }
- } catch (IOException e) {
- err = GenericUtils.accumulateException(err, e);
- }
- }
-
- return err;
- }
-
- /**
- * @param fileName The file name to be evaluated - ignored if {@code null}/empty
- * @return {@code true} if the file ends in one of the {@link #WINDOWS_EXECUTABLE_EXTENSIONS}
- */
- public static boolean isWindowsExecutable(String fileName) {
- if ((fileName == null) || (fileName.length() <= 0)) {
- return false;
- }
- for (String suffix : WINDOWS_EXECUTABLE_EXTENSIONS) {
- if (fileName.endsWith(suffix)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * If the "posix" view is supported, then it returns
- * {@link Files#getPosixFilePermissions(Path, LinkOption...)}, otherwise
- * uses the {@link #getPermissionsFromFile(File)} method
- *
- * @param path The {@link Path}
- * @param options The {@link LinkOption}s to use when querying the permissions
- * @return A {@link Set} of {@link PosixFilePermission}
- * @throws IOException If failed to access the file system in order to
- * retrieve the permissions
- */
- public static Set<PosixFilePermission> getPermissions(Path path, LinkOption... options) throws IOException {
- FileSystem fs = path.getFileSystem();
- Collection<String> views = fs.supportedFileAttributeViews();
- if (views.contains("posix")) {
- return Files.getPosixFilePermissions(path, options);
- } else {
- return getPermissionsFromFile(path.toFile());
- }
- }
-
- /**
- * @param f The {@link File} to be checked
- * @return A {@link Set} of {@link PosixFilePermission}s based on whether
- * the file is readable/writable/executable. If so, then <U>all</U> the
- * relevant permissions are set (i.e., owner, group and others)
- */
- public static Set<PosixFilePermission> getPermissionsFromFile(File f) {
- Set<PosixFilePermission> perms = EnumSet.noneOf(PosixFilePermission.class);
- if (f.canRead()) {
- perms.add(PosixFilePermission.OWNER_READ);
- perms.add(PosixFilePermission.GROUP_READ);
- perms.add(PosixFilePermission.OTHERS_READ);
- }
-
- if (f.canWrite()) {
- perms.add(PosixFilePermission.OWNER_WRITE);
- perms.add(PosixFilePermission.GROUP_WRITE);
- perms.add(PosixFilePermission.OTHERS_WRITE);
- }
-
- if (isExecutable(f)) {
- perms.add(PosixFilePermission.OWNER_EXECUTE);
- perms.add(PosixFilePermission.GROUP_EXECUTE);
- perms.add(PosixFilePermission.OTHERS_EXECUTE);
- }
-
- return perms;
- }
-
- public static boolean isExecutable(File f) {
- if (f == null) {
- return false;
- }
-
- if (OsUtils.isWin32()) {
- return isWindowsExecutable(f.getName());
- } else {
- return f.canExecute();
- }
- }
-
- /**
- * If the "posix" view is supported, then it invokes
- * {@link Files#setPosixFilePermissions(Path, Set)}, otherwise
- * uses the {@link #setPermissionsToFile(File, Collection)} method
- *
- * @param path The {@link Path}
- * @param perms The {@link Set} of {@link PosixFilePermission}s
- * @throws IOException If failed to access the file system
- */
- public static void setPermissions(Path path, Set<PosixFilePermission> perms) throws IOException {
- FileSystem fs = path.getFileSystem();
- Collection<String> views = fs.supportedFileAttributeViews();
- if (views.contains("posix")) {
- Files.setPosixFilePermissions(path, perms);
- } else {
- setPermissionsToFile(path.toFile(), perms);
- }
- }
-
- /**
- * @param f The {@link File}
- * @param perms A {@link Collection} of {@link PosixFilePermission}s to set on it.
- * <B>Note:</B> the file is set to readable/writable/executable not only by the
- * owner if <U>any</U> of relevant the owner/group/others permission is set
- */
- public static void setPermissionsToFile(File f, Collection<PosixFilePermission> perms) {
- boolean readable = perms != null
- && (perms.contains(PosixFilePermission.OWNER_READ)
- || perms.contains(PosixFilePermission.GROUP_READ)
- || perms.contains(PosixFilePermission.OTHERS_READ));
- f.setReadable(readable, false);
-
- boolean writable = perms != null
- && (perms.contains(PosixFilePermission.OWNER_WRITE)
- || perms.contains(PosixFilePermission.GROUP_WRITE)
- || perms.contains(PosixFilePermission.OTHERS_WRITE));
- f.setWritable(writable, false);
-
- boolean executable = perms != null
- && (perms.contains(PosixFilePermission.OWNER_EXECUTE)
- || perms.contains(PosixFilePermission.GROUP_EXECUTE)
- || perms.contains(PosixFilePermission.OTHERS_EXECUTE));
- f.setExecutable(executable, false);
- }
-
- /**
- * <P>Get file owner.</P>
- *
- * @param path The {@link Path}
- * @param options The {@link LinkOption}s to use when querying the owner
- * @return Owner of the file or null if unsupported. <B>Note:</B> for
- * <I>Windows</I> it strips any prepended domain or group name
- * @throws IOException If failed to access the file system
- * @see Files#getOwner(Path, LinkOption...)
- */
- public static String getFileOwner(Path path, LinkOption... options) throws IOException {
- try {
- UserPrincipal principal = Files.getOwner(path, options);
- String owner = (principal == null) ? null : principal.getName();
- return OsUtils.getCanonicalUser(owner);
- } catch (UnsupportedOperationException e) {
- return null;
- }
- }
-
- /**
- * <P>Checks if a file exists - <B>Note:</B> according to the
- * <A HREF="http://docs.oracle.com/javase/tutorial/essential/io/check.html">Java tutorial - Checking a File or Directory</A>:
- * </P>
- *
- * <PRE>
- * The methods in the Path class are syntactic, meaning that they operate
- * on the Path instance. But eventually you must access the file system
- * to verify that a particular Path exists, or does not exist. You can do
- * so with the exists(Path, LinkOption...) and the notExists(Path, LinkOption...)
- * methods. Note that !Files.exists(path) is not equivalent to Files.notExists(path).
- * When you are testing a file's existence, three results are possible:
- *
- * - The file is verified to exist.
- * - The file is verified to not exist.
- * - The file's status is unknown.
- *
- * This result can occur when the program does not have access to the file.
- * If both exists and notExists return false, the existence of the file cannot
- * be verified.
- * </PRE>
- *
- * @param path The {@link Path} to be tested
- * @param options The {@link LinkOption}s to use
- * @return {@link Boolean#TRUE}/{@link Boolean#FALSE} or {@code null}
- * according to the file status as explained above
- */
- public static Boolean checkFileExists(Path path, LinkOption... options) {
- if (Files.exists(path, options)) {
- return Boolean.TRUE;
- } else if (Files.notExists(path, options)) {
- return Boolean.FALSE;
- } else {
- return null;
- }
- }
-
- /**
- * Read the requested number of bytes or fail if there are not enough left.
- *
- * @param input where to read input from
- * @param buffer destination
- * @throws IOException if there is a problem reading the file
- * @throws EOFException if the number of bytes read was incorrect
- */
- public static void readFully(InputStream input, byte[] buffer) throws IOException {
- readFully(input, buffer, 0, buffer.length);
- }
-
- /**
- * Read the requested number of bytes or fail if there are not enough left.
- *
- * @param input where to read input from
- * @param buffer destination
- * @param offset initial offset into buffer
- * @param length length to read, must be ≥ 0
- * @throws IOException if there is a problem reading the file
- * @throws EOFException if the number of bytes read was incorrect
- */
- public static void readFully(InputStream input, byte[] buffer, int offset, int length) throws IOException {
- int actual = read(input, buffer, offset, length);
- if (actual != length) {
- throw new EOFException("Premature EOF - expected=" + length + ", actual=" + actual);
- }
- }
-
- /**
- * Read as many bytes as possible until EOF or achieved required length
- *
- * @param input where to read input from
- * @param buffer destination
- * @return actual length read; may be less than requested if EOF was reached
- * @throws IOException if a read error occurs
- */
- public static int read(InputStream input, byte[] buffer) throws IOException {
- return read(input, buffer, 0, buffer.length);
- }
-
- /**
- * Read as many bytes as possible until EOF or achieved required length
- *
- * @param input where to read input from
- * @param buffer destination
- * @param offset initial offset into buffer
- * @param length length to read - ignored if non-positive
- * @return actual length read; may be less than requested if EOF was reached
- * @throws IOException if a read error occurs
- */
- public static int read(InputStream input, byte[] buffer, int offset, int length) throws IOException {
- for (int remaining = length, curOffset = offset; remaining > 0;) {
- int count = input.read(buffer, curOffset, remaining);
- if (count == -1) { // EOF before achieved required length
- return curOffset - offset;
- }
-
- remaining -= count;
- curOffset += count;
- }
-
- return length;
- }
-
- /**
- * @param perms The current {@link PosixFilePermission}s - ignored if {@code null}/empty
- * @param excluded The permissions <U>not</U> allowed to exist - ignored if {@code null}/empty
- * @return The violating {@link PosixFilePermission} - {@code null}
- * if no violating permission found
- */
- public static PosixFilePermission validateExcludedPermissions(Collection<PosixFilePermission> perms, Collection<PosixFilePermission> excluded) {
- if (GenericUtils.isEmpty(perms) || GenericUtils.isEmpty(excluded)) {
- return null;
- }
-
- for (PosixFilePermission p : excluded) {
- if (perms.contains(p)) {
- return p;
- }
- }
-
- return null;
- }
-
- /**
- * @param path The {@link Path} to check
- * @param options The {@link LinkOption}s to use when checking if path is a directory
- * @return The same input path if it is a directory
- * @throws UnsupportedOperationException if input path not a directory
- */
- public static Path ensureDirectory(Path path, LinkOption... options) {
- if (!Files.isDirectory(path, options)) {
- throw new UnsupportedOperationException("Not a directory: " + path);
- }
- return path;
- }
-
- /**
- * @param options The {@link LinkOption}s - OK if {@code null}/empty
- * @return {@code true} if the link options are {@code null}/empty or do
- * not contain {@link LinkOption#NOFOLLOW_LINKS}, {@code false} otherwise
- * (i.e., the array is not empty and contains the special value)
- */
- public static boolean followLinks(LinkOption... options) {
- if (GenericUtils.isEmpty(options)) {
- return true;
- }
-
- for (LinkOption localLinkOption : options) {
- if (localLinkOption == LinkOption.NOFOLLOW_LINKS) {
- return false;
- }
- }
- return true;
- }
-
- public static String appendPathComponent(String prefix, String component) {
- if (GenericUtils.isEmpty(prefix)) {
- return component;
- }
-
- if (GenericUtils.isEmpty(component)) {
- return prefix;
- }
-
- StringBuilder sb = new StringBuilder(prefix.length() + component.length() + File.separator.length()).append(prefix);
-
- if (sb.charAt(prefix.length() - 1) == File.separatorChar) {
- if (component.charAt(0) == File.separatorChar) {
- sb.append(component.substring(1));
- } else {
- sb.append(component);
- }
- } else {
- if (component.charAt(0) != File.separatorChar) {
- sb.append(File.separatorChar);
- }
- sb.append(component);
- }
-
- return sb.toString();
- }
-
- public static byte[] toByteArray(InputStream inStream) throws IOException {
- try (ByteArrayOutputStream baos = new ByteArrayOutputStream(DEFAULT_COPY_SIZE)) {
- copy(inStream, baos);
- return baos.toByteArray();
- }
- }
-
- /**
- * Reads all lines until no more available
- *
- * @param url The {@link URL} to read from
- * @return The {@link List} of lines in the same <U>order</U> as it was read
- * @throws IOException If failed to read the lines
- * @see #readAllLines(InputStream)
- */
- public static List<String> readAllLines(URL url) throws IOException {
- try (InputStream stream = Objects.requireNonNull(url, "No URL").openStream()) {
- return readAllLines(stream);
- }
- }
-
- /**
- * Reads all lines until no more available
- *
- * @param stream The {@link InputStream} - <B>Note:</B> assumed to
- * contain {@code UTF-8} encoded data
- * @return The {@link List} of lines in the same <U>order</U> as it was read
- * @throws IOException If failed to read the lines
- * @see #readAllLines(Reader)
- */
- public static List<String> readAllLines(InputStream stream) throws IOException {
- try (Reader reader = new InputStreamReader(Objects.requireNonNull(stream, "No stream instance"), StandardCharsets.UTF_8)) {
- return readAllLines(reader);
- }
- }
-
- public static List<String> readAllLines(Reader reader) throws IOException {
- try (BufferedReader br = new BufferedReader(Objects.requireNonNull(reader, "No reader instance"), DEFAULT_COPY_SIZE)) {
- return readAllLines(br);
- }
- }
-
- /**
- * Reads all lines until no more available
- *
- * @param reader The {@link BufferedReader} to read all lines
- * @return The {@link List} of lines in the same <U>order</U> as it was read
- * @throws IOException If failed to read the lines
- * @see #readAllLines(BufferedReader, int)
- */
- public static List<String> readAllLines(BufferedReader reader) throws IOException {
- return readAllLines(reader, -1);
- }
-
- /**
- * Reads all lines until no more available
- *
- * @param reader The {@link BufferedReader} to read all lines
- * @param lineCountHint A hint as to the expected number of lines - non-positive
- * means unknown - in which case some initial default value will be used to
- * initialize the list used to accumulate the lines.
- * @return The {@link List} of lines in the same <U>order</U> as it was read
- * @throws IOException If failed to read the lines
- */
- public static List<String> readAllLines(BufferedReader reader, int lineCountHint) throws IOException {
- List<String> result = new ArrayList<>(Math.max(lineCountHint, Short.SIZE));
- for (String line = reader.readLine(); line != null; line = reader.readLine()) {
- result.add(line);
- }
- return result;
- }
-}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/util/io/LimitInputStream.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/io/LimitInputStream.java b/sshd-core/src/main/java/org/apache/sshd/common/util/io/LimitInputStream.java
deleted file mode 100644
index bbf956a..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/io/LimitInputStream.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * 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.common.util.io;
-
-import java.io.FilterInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.channels.Channel;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-/**
- * Reads from another {@link InputStream} up to specified max. length
- *
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public class LimitInputStream extends FilterInputStream implements Channel {
- private final AtomicBoolean open = new AtomicBoolean(true);
- private long remaining;
-
- public LimitInputStream(InputStream in, long length) {
- super(in);
- remaining = length;
- }
-
- @Override
- public boolean isOpen() {
- return open.get();
- }
-
- @Override
- public int read() throws IOException {
- if (!isOpen()) {
- throw new IOException("read() - stream is closed (remaining=" + remaining + ")");
- }
-
- if (remaining > 0) {
- remaining--;
- return super.read();
- } else {
- return -1;
- }
- }
-
- @Override
- public int read(byte[] b, int off, int len) throws IOException {
- if (!isOpen()) {
- throw new IOException("read(len=" + len + ") stream is closed (remaining=" + remaining + ")");
- }
-
- int nb = len;
- if (nb > remaining) {
- nb = (int) remaining;
- }
- if (nb > 0) {
- int read = super.read(b, off, nb);
- remaining -= read;
- return read;
- } else {
- return -1;
- }
- }
-
- @Override
- public long skip(long n) throws IOException {
- if (!isOpen()) {
- throw new IOException("skip(" + n + ") stream is closed (remaining=" + remaining + ")");
- }
-
- long skipped = super.skip(n);
- remaining -= skipped;
- return skipped;
- }
-
- @Override
- public int available() throws IOException {
- if (!isOpen()) {
- throw new IOException("available() stream is closed (remaining=" + remaining + ")");
- }
-
- int av = super.available();
- if (av > remaining) {
- return (int) remaining;
- } else {
- return av;
- }
- }
-
- @Override
- public void close() throws IOException {
- // do not close the original input stream since it serves for ACK(s)
- if (open.getAndSet(false)) {
- //noinspection UnnecessaryReturnStatement
- return; // debug breakpoint
- }
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/util/io/LoggingFilterOutputStream.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/io/LoggingFilterOutputStream.java b/sshd-core/src/main/java/org/apache/sshd/common/util/io/LoggingFilterOutputStream.java
deleted file mode 100644
index ff4dbb6..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/io/LoggingFilterOutputStream.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * 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.common.util.io;
-
-import java.io.FilterOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.apache.sshd.common.PropertyResolver;
-import org.apache.sshd.common.util.buffer.BufferUtils;
-import org.apache.sshd.common.util.logging.LoggingUtils;
-import org.apache.sshd.common.util.logging.SimplifiedLog;
-import org.slf4j.Logger;
-
-/**
- * Dumps everything that is written to the stream to the logger
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public class LoggingFilterOutputStream extends FilterOutputStream {
-
- private final String msg;
- private final SimplifiedLog log;
- private final int chunkSize;
- private final AtomicInteger writeCount = new AtomicInteger(0);
-
- public LoggingFilterOutputStream(OutputStream out, String msg, Logger log, PropertyResolver resolver) {
- this(out, msg, log, resolver.getIntProperty(BufferUtils.HEXDUMP_CHUNK_SIZE, BufferUtils.DEFAULT_HEXDUMP_CHUNK_SIZE));
- }
-
- public LoggingFilterOutputStream(OutputStream out, String msg, Logger log, int chunkSize) {
- super(out);
- this.msg = msg;
- this.log = LoggingUtils.wrap(log);
- this.chunkSize = chunkSize;
- }
-
- @Override
- public void write(int b) throws IOException {
- byte[] d = new byte[1];
- d[0] = (byte) b;
- write(d, 0, 1);
- }
-
- @Override
- public void write(byte[] b, int off, int len) throws IOException {
- int count = writeCount.incrementAndGet();
- BufferUtils.dumpHex(log, BufferUtils.DEFAULT_HEXDUMP_LEVEL, msg + "[" + count + "]", BufferUtils.DEFAULT_HEX_SEPARATOR, chunkSize, b, off, len);
- out.write(b, off, len);
- }
-}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/util/io/ModifiableFileWatcher.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/io/ModifiableFileWatcher.java b/sshd-core/src/main/java/org/apache/sshd/common/util/io/ModifiableFileWatcher.java
deleted file mode 100644
index 032260b..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/io/ModifiableFileWatcher.java
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * 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.common.util.io;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.LinkOption;
-import java.nio.file.Path;
-import java.nio.file.attribute.BasicFileAttributes;
-import java.nio.file.attribute.FileTime;
-import java.nio.file.attribute.PosixFilePermission;
-import java.util.AbstractMap.SimpleImmutableEntry;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.HashSet;
-import java.util.Objects;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicLong;
-
-import org.apache.sshd.common.util.GenericUtils;
-import org.apache.sshd.common.util.OsUtils;
-import org.apache.sshd.common.util.logging.AbstractLoggingBean;
-
-/**
- * Watches over changes for a file and re-loads them if file has changed - including
- * if file is deleted or (re-)created
- *
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public class ModifiableFileWatcher extends AbstractLoggingBean {
-
- /**
- * The {@link Set} of {@link PosixFilePermission} <U>not</U> allowed if strict
- * permissions are enforced on key files
- */
- public static final Set<PosixFilePermission> STRICTLY_PROHIBITED_FILE_PERMISSION =
- Collections.unmodifiableSet(
- EnumSet.of(PosixFilePermission.GROUP_WRITE, PosixFilePermission.OTHERS_WRITE));
-
- protected final LinkOption[] options;
-
- private final Path file;
- private final AtomicBoolean lastExisted = new AtomicBoolean(false);
- private final AtomicLong lastSize = new AtomicLong(Long.MIN_VALUE);
- private final AtomicLong lastModified = new AtomicLong(-1L);
-
- public ModifiableFileWatcher(File file) {
- this(Objects.requireNonNull(file, "No file to watch").toPath());
- }
-
- public ModifiableFileWatcher(Path file) {
- this(file, IoUtils.getLinkOptions(true));
- }
-
- public ModifiableFileWatcher(Path file, LinkOption... options) {
- this.file = Objects.requireNonNull(file, "No path to watch");
- // use a clone to avoid being sensitive to changes in the passed array
- this.options = (options == null) ? IoUtils.EMPTY_LINK_OPTIONS : options.clone();
- }
-
- /**
- * @return The watched {@link Path}
- */
- public final Path getPath() {
- return file;
- }
-
- public final boolean exists() throws IOException {
- return Files.exists(getPath(), options);
- }
-
- public final long size() throws IOException {
- if (exists()) {
- return Files.size(getPath());
- } else {
- return -1L;
- }
- }
-
- public final FileTime lastModified() throws IOException {
- if (exists()) {
- BasicFileAttributes attrs = Files.readAttributes(getPath(), BasicFileAttributes.class, options);
- return attrs.lastModifiedTime();
- } else {
- return null;
- }
- }
-
- /**
- * @return {@code true} if the watched file has probably been changed
- * @throws IOException If failed to query file data
- */
- public boolean checkReloadRequired() throws IOException {
- boolean exists = exists();
- // if existence state changed from last time
- if (exists != lastExisted.getAndSet(exists)) {
- return true;
- }
-
- if (!exists) {
- // file did not exist and still does not exist
- resetReloadAttributes();
- return false;
- }
-
- long size = size();
- if (size < 0L) {
- // means file no longer exists
- resetReloadAttributes();
- return true;
- }
-
- // if size changed then obviously need reload
- if (size != lastSize.getAndSet(size)) {
- return true;
- }
-
- FileTime modifiedTime = lastModified();
- if (modifiedTime == null) {
- // means file no longer exists
- resetReloadAttributes();
- return true;
- }
-
- long timestamp = modifiedTime.toMillis();
- return timestamp != lastModified.getAndSet(timestamp);
-
- }
-
- /**
- * Resets the state attributes used to detect changes to the initial
- * construction values - i.e., file assumed not to exist and no known
- * size of modify time
- */
- public void resetReloadAttributes() {
- lastExisted.set(false);
- lastSize.set(Long.MIN_VALUE);
- lastModified.set(-1L);
- }
-
- /**
- * May be called to refresh the state attributes used to detect changes
- * e.g., file existence, size and last-modified time once re-loading is
- * successfully completed. If the file does not exist then the attributes
- * are reset to an "unknown" state.
- *
- * @throws IOException If failed to access the file (if exists)
- * @see #resetReloadAttributes()
- */
- public void updateReloadAttributes() throws IOException {
- if (exists()) {
- long size = size();
- FileTime modifiedTime = lastModified();
-
- if ((size >= 0L) && (modifiedTime != null)) {
- lastExisted.set(true);
- lastSize.set(size);
- lastModified.set(modifiedTime.toMillis());
- return;
- }
- }
-
- resetReloadAttributes();
- }
-
- @Override
- public String toString() {
- return Objects.toString(getPath());
- }
-
- /**
- * <P>Checks if a path has strict permissions</P>
- * <UL>
- *
- * <LI><P>
- * (For {@code Unix}) The path may not have group or others write permissions
- * </P></LI>
- *
- * <LI><P>
- * The path must be owned by current user.
- * </P></LI>
- *
- * <LI><P>
- * (For {@code Unix}) The path may be owned by root.
- * </P></LI>
- *
- * </UL>
- *
- * @param path The {@link Path} to be checked - ignored if {@code null}
- * or does not exist
- * @param options The {@link LinkOption}s to use to query the file's permissions
- * @return The violated permission as {@link SimpleImmutableEntry} where key
- * is a loggable message and value is the offending object
- * - e.g., {@link PosixFilePermission} or {@link String} for owner. Return
- * value is {@code null} if no violations detected
- * @throws IOException If failed to retrieve the permissions
- * @see #STRICTLY_PROHIBITED_FILE_PERMISSION
- */
- public static SimpleImmutableEntry<String, Object> validateStrictConfigFilePermissions(Path path, LinkOption... options) throws IOException {
- if ((path == null) || (!Files.exists(path, options))) {
- return null;
- }
-
- Collection<PosixFilePermission> perms = IoUtils.getPermissions(path, options);
- if (GenericUtils.isEmpty(perms)) {
- return null;
- }
-
- if (OsUtils.isUNIX()) {
- PosixFilePermission p = IoUtils.validateExcludedPermissions(perms, STRICTLY_PROHIBITED_FILE_PERMISSION);
- if (p != null) {
- return new SimpleImmutableEntry<>(String.format("Permissions violation (%s)", p), p);
- }
- }
-
- String owner = IoUtils.getFileOwner(path, options);
- if (GenericUtils.isEmpty(owner)) {
- // we cannot get owner
- // general issue: jvm does not support permissions
- // security issue: specific filesystem does not support permissions
- return null;
- }
-
- String current = OsUtils.getCurrentUser();
- Set<String> expected = new HashSet<>();
- expected.add(current);
- if (OsUtils.isUNIX()) {
- // Windows "Administrator" was considered however in Windows most likely a group is used.
- expected.add(OsUtils.ROOT_USER);
- }
-
- if (!expected.contains(owner)) {
- return new SimpleImmutableEntry<>(String.format("Owner violation (%s)", owner), owner);
- }
-
- return null;
- }
-}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/util/io/NoCloseInputStream.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/io/NoCloseInputStream.java b/sshd-core/src/main/java/org/apache/sshd/common/util/io/NoCloseInputStream.java
deleted file mode 100644
index b9aedee..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/io/NoCloseInputStream.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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.common.util.io;
-
-import java.io.FilterInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * TODO Add javadoc
- *
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public class NoCloseInputStream extends FilterInputStream {
- public NoCloseInputStream(InputStream in) {
- super(in);
- }
-
- @Override
- public void close() throws IOException {
- // ignored
- }
-
- public static InputStream resolveInputStream(InputStream input, boolean okToClose) {
- if ((input == null) || okToClose) {
- return input;
- } else {
- return new NoCloseInputStream(input);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/util/io/NoCloseOutputStream.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/io/NoCloseOutputStream.java b/sshd-core/src/main/java/org/apache/sshd/common/util/io/NoCloseOutputStream.java
deleted file mode 100644
index 4ba16d3..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/io/NoCloseOutputStream.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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.common.util.io;
-
-import java.io.FilterOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-
-/**
- * TODO Add javadoc
- *
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public class NoCloseOutputStream extends FilterOutputStream {
- public NoCloseOutputStream(OutputStream out) {
- super(out);
- }
-
- @Override
- public void close() throws IOException {
- // ignored
- }
-
- public static OutputStream resolveOutputStream(OutputStream output, boolean okToClose) {
- if ((output == null) || okToClose) {
- return output;
- } else {
- return new NoCloseOutputStream(output);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/util/io/NoCloseReader.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/io/NoCloseReader.java b/sshd-core/src/main/java/org/apache/sshd/common/util/io/NoCloseReader.java
deleted file mode 100644
index 9c8b218..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/io/NoCloseReader.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.common.util.io;
-
-import java.io.FilterReader;
-import java.io.IOException;
-import java.io.Reader;
-
-/**
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public class NoCloseReader extends FilterReader {
- public NoCloseReader(Reader in) {
- super(in);
- }
-
- @Override
- public void close() throws IOException {
- // ignored
- }
-
- public static Reader resolveReader(Reader r, boolean okToClose) {
- if ((r == null) || okToClose) {
- return r;
- } else {
- return new NoCloseReader(r);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/util/io/NoCloseWriter.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/io/NoCloseWriter.java b/sshd-core/src/main/java/org/apache/sshd/common/util/io/NoCloseWriter.java
deleted file mode 100644
index 0f92697..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/io/NoCloseWriter.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.common.util.io;
-
-import java.io.FilterWriter;
-import java.io.IOException;
-import java.io.Writer;
-
-/**
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public class NoCloseWriter extends FilterWriter {
- public NoCloseWriter(Writer out) {
- super(out);
- }
-
- @Override
- public void close() throws IOException {
- // ignored
- }
-
- public static Writer resolveWriter(Writer r, boolean okToClose) {
- if ((r == null) || okToClose) {
- return r;
- } else {
- return new NoCloseWriter(r);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/util/io/NullInputStream.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/io/NullInputStream.java b/sshd-core/src/main/java/org/apache/sshd/common/util/io/NullInputStream.java
deleted file mode 100644
index eb21383..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/io/NullInputStream.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * 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.common.util.io;
-
-import java.io.EOFException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.channels.Channel;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-/**
- * A {@code /dev/null} input stream
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public class NullInputStream extends InputStream implements Channel {
- private final AtomicBoolean open = new AtomicBoolean(true);
-
- public NullInputStream() {
- super();
- }
-
- @Override
- public boolean isOpen() {
- return open.get();
- }
-
- @Override
- public int read() throws IOException {
- if (!isOpen()) {
- throw new EOFException("Stream is closed for reading one value");
- }
- return -1;
- }
-
- @Override
- public int read(byte[] b, int off, int len) throws IOException {
- if (!isOpen()) {
- throw new EOFException("Stream is closed for reading " + len + " bytes");
- }
- return -1;
- }
-
- @Override
- public long skip(long n) throws IOException {
- if (!isOpen()) {
- throw new EOFException("Stream is closed for skipping " + n + " bytes");
- }
- return 0L;
- }
-
- @Override
- public int available() throws IOException {
- if (!isOpen()) {
- throw new EOFException("Stream is closed for availability query");
- }
- return 0;
- }
-
- @Override
- public synchronized void reset() throws IOException {
- if (!isOpen()) {
- throw new EOFException("Stream is closed for reset");
- }
- }
-
- @Override
- public void close() throws IOException {
- if (open.getAndSet(false)) {
- //noinspection UnnecessaryReturnStatement
- return; // debug breakpoint
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/util/io/NullOutputStream.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/io/NullOutputStream.java b/sshd-core/src/main/java/org/apache/sshd/common/util/io/NullOutputStream.java
deleted file mode 100644
index 67fa2d0..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/io/NullOutputStream.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * 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.common.util.io;
-
-import java.io.EOFException;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.nio.channels.Channel;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-/**
- * A {code /dev/null} output stream
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public class NullOutputStream extends OutputStream implements Channel {
- private final AtomicBoolean open = new AtomicBoolean(true);
-
- public NullOutputStream() {
- super();
- }
-
- @Override
- public boolean isOpen() {
- return open.get();
- }
-
- @Override
- public void write(int b) throws IOException {
- if (!isOpen()) {
- throw new EOFException("Stream is closed for writing one byte");
- }
- }
-
- @Override
- public void write(byte[] b, int off, int len) throws IOException {
- if (!isOpen()) {
- throw new EOFException("Stream is closed for writing " + len + " bytes");
- }
- }
-
- @Override
- public void flush() throws IOException {
- if (!isOpen()) {
- throw new EOFException("Stream is closed for flushing");
- }
- }
-
- @Override
- public void close() throws IOException {
- if (open.getAndSet(false)) {
- //noinspection UnnecessaryReturnStatement
- return; // debug breakpoint
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/util/io/OutputStreamWithChannel.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/io/OutputStreamWithChannel.java b/sshd-core/src/main/java/org/apache/sshd/common/util/io/OutputStreamWithChannel.java
deleted file mode 100644
index 6f81872..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/io/OutputStreamWithChannel.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.common.util.io;
-
-import java.io.OutputStream;
-import java.nio.channels.Channel;
-
-/**
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public abstract class OutputStreamWithChannel extends OutputStream implements Channel {
- protected OutputStreamWithChannel() {
- super();
- }
-}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/10de190e/sshd-core/src/main/java/org/apache/sshd/common/util/io/der/ASN1Class.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/io/der/ASN1Class.java b/sshd-core/src/main/java/org/apache/sshd/common/util/io/der/ASN1Class.java
deleted file mode 100644
index b8351f1..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/io/der/ASN1Class.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * 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.common.util.io.der;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-import org.apache.sshd.common.util.GenericUtils;
-
-/**
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public enum ASN1Class {
- // NOTE: order is crucial, so DON'T change it
- UNIVERSAL((byte) 0x00),
- APPLICATION((byte) 0x01),
- CONTEXT((byte) 0x02),
- PRIVATE((byte) 0x03);
-
- public static final List<ASN1Class> VALUES =
- Collections.unmodifiableList(Arrays.asList(values()));
-
- private final byte byteValue;
-
- ASN1Class(byte classValue) {
- byteValue = classValue;
- }
-
- public byte getClassValue() {
- return byteValue;
- }
-
- public static ASN1Class fromName(String s) {
- if (GenericUtils.isEmpty(s)) {
- return null;
- }
-
- for (ASN1Class c : VALUES) {
- if (s.equalsIgnoreCase(c.name())) {
- return c;
- }
- }
-
- return null;
- }
-
- /**
- * <P>The first byte in DER encoding is made of following fields</P>
- * <pre>
- *-------------------------------------------------
- *|Bit 8|Bit 7|Bit 6|Bit 5|Bit 4|Bit 3|Bit 2|Bit 1|
- *-------------------------------------------------
- *| Class | CF | Type |
- *-------------------------------------------------
- * </pre>
- * @param value The original DER encoded byte
- * @return The {@link ASN1Class} value - {@code null} if no match found
- * @see #fromTypeValue(int)
- */
- public static ASN1Class fromDERValue(int value) {
- return fromTypeValue((value >> 6) & 0x03);
- }
-
- /**
- * @param value The "pure" value - unshifted and with no extras
- * @return The {@link ASN1Class} value - {@code null} if no match found
- */
- public static ASN1Class fromTypeValue(int value) {
- // all 4 values are defined
- if ((value < 0) || (value >= VALUES.size())) {
- return null;
- }
-
- return VALUES.get(value);
- }
-}