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:[email protected]">[email protected]</a> - * @author Magesh Umasankar - * @author <a href="mailto:[email protected]">Bruce Atherton</a> - * @author <a href="mailto:[email protected]">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:[email protected]">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:[email protected]">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:[email protected]">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:[email protected]">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:[email protected]">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:[email protected]">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:[email protected]">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:[email protected]">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:[email protected]">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:[email protected]">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:[email protected]">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:[email protected]">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:[email protected]">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:[email protected]">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:[email protected]">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); - } -}
