/** * Ensures configured directory {@code path} exists. * @throws IOException if {@code path} exists, but is not a directory, not accessible, or broken symbolic link. */ static void ensureDirectoryExists(Path path) throws IOException { // this isn't atomic, but neither is createDirectories. if (Files.isDirectory(path)) { // verify access, following links (throws exception if something is wrong) // we only check READ as a sanity test path.getFileSystem().provider().checkAccess(path.toRealPath(), AccessMode.READ); } else { // doesn't exist, or not a directory try { Files.createDirectories(path); } catch (FileAlreadyExistsException e) { // convert optional specific exception so the context is clear IOException e2 = new NotDirectoryException(path.toString()); e2.addSuppressed(e); throw e2; } } }
/** * Starts this Muxer, if not already started. * * This is thread safe to be called at any time, multiple times. Returns immediately. * * @throws IOException */ public void start() throws IOException { if (state.compareAndSet(NOT_STARTED, RUNNING)) { try { access(mkv, AccessMode.READ); access(srt, AccessMode.READ); access(tempDir, AccessMode.WRITE); output.toFile().deleteOnExit(); ProcessBuilder builder = factory.from("mkvmerge", "-o", output.toString(), mkv.toString(), srt.toString()); builder.directory(tempDir.toFile()).inheritIO(); // TODO: Better solution than inheritIO process = builder.start(); } catch (Exception e) { state.set(FAILED); deleteWarn(output); throw e; } } }
@Override public void checkAccess(Path path, AccessMode... modes) throws IOException { CloudPath cloudPath = getCloudPath(path); CloudFileSystemImplementation sourceCloudFileSystemImplementation = getCloudFileSystemImplementation(cloudPath); // Work out permissions to check Set<AclEntryPermission> checkPermissions = EnumSet.noneOf(AclEntryPermission.class); Arrays.stream(modes).forEach(m -> { if (AccessMode.EXECUTE.equals(m)) { checkPermissions.add(AclEntryPermission.EXECUTE); } else if (AccessMode.READ.equals(m)) { checkPermissions.add(AclEntryPermission.READ_DATA); } else if (AccessMode.WRITE.equals(m)) { checkPermissions.add(AclEntryPermission.WRITE_DATA); } }); sourceCloudFileSystemImplementation.checkAccess(getBlobStoreContext(cloudPath), cloudPath, checkPermissions); }
public AbstractLocalFileSystem( URI uri, FileSystemProvider provider, Path cachePath, Map<String, Object> env, BiFunction<Path, Map<String, ?>, FileSystemIO> fileSystemIO ) throws IOException { super( uri, provider, env, cachePath, fileSystemIO ); this.cachePath = getFileSystemIO().getBaseDirectory(); if( Files.notExists( cachePath ) ) { Files.createDirectories( cachePath ); } // sm and existence check cachePath.getFileSystem().provider().checkAccess( cachePath, AccessMode.READ ); if( !Files.isWritable( cachePath ) ) { setReadOnly( true ); } }
@Override public void checkAccess(Path path, AccessMode... modes) throws IOException { JPath jPath = (JPath) path; Status status; try { status = jPath.getBfsFile().getStatus(); } catch (Exception e) { throw createIOException(e); } if (status.getType() == Status.FileType.FILE) { // do nothing } else if (status.getType() == Status.FileType.DIRECTORY) { // do nothing } else { throw new NoSuchFileException(path.toUri().toString()); } }
/** {@inheritDoc} */ @Override public void move(Path source, Path target, CopyOption... options) throws IOException { source = ((TestPath) source).unwrap(); target = ((TestPath) target).unwrap(); checkIfRemoved(source); Path sourceParent = source.getParent(); if (sourceParent != null) { checkIfRemoved(sourceParent); checkPermissions(sourceParent, true, AccessMode.WRITE); } Path targetParent = target.getParent(); if (targetParent != null) { checkIfRemoved(targetParent); checkPermissions(targetParent, true, AccessMode.WRITE); } provider.move(source, target, options); }
protected AbstractTarFileSystem(AbstractTarFileSystemProvider provider, Path tfpath, Map<String, ?> env) throws IOException { // configurable env setup createNew = "true".equals(env.get("create")); defaultDir = env.containsKey("default.dir") ? (String) env .get("default.dir") : "/"; entriesToData = new HashMap<>(); if (defaultDir.charAt(0) != '/') { throw new IllegalArgumentException("default dir should be absolute"); } this.provider = provider; this.tfpath = tfpath; if (Files.notExists(tfpath)) { if (!createNew) { throw new FileSystemNotFoundException(tfpath.toString()); } } // sm and existence check tfpath.getFileSystem().provider().checkAccess(tfpath, AccessMode.READ); if (!Files.isWritable(tfpath)) { readOnly = true; } defaultdir = new TarPath(this, defaultDir.getBytes()); outputStreams = new ArrayList<>(); mapEntries(); }
public Set<AccessMode> accessModeMaskToSet(int mask) { Set<AccessMode> accessModes = EnumSet.noneOf(AccessMode.class); // @formatter:off if ((mask & AccessConstants.R_OK) == AccessConstants.R_OK) accessModes.add(AccessMode.READ); if ((mask & AccessConstants.W_OK) == AccessConstants.W_OK) accessModes.add(AccessMode.WRITE); if ((mask & AccessConstants.X_OK) == AccessConstants.X_OK) accessModes.add(AccessMode.EXECUTE); // @formatter:on return accessModes; }
@Override public int access(String path, int mask) { try { Path node = resolvePath(path); Set<AccessMode> accessModes = attrUtil.accessModeMaskToSet(mask); return checkAccess(node, accessModes); } catch (RuntimeException e) { LOG.error("checkAccess failed.", e); return -ErrorCodes.EIO(); } }
@ParameterizedTest @MethodSource("accessModeProvider") public void testAccessModeMaskToSet(Set<AccessMode> expectedModes, int mask) { FileAttributesUtil util = new FileAttributesUtil(); Set<AccessMode> accessModes = util.accessModeMaskToSet(mask); Assertions.assertEquals(expectedModes, accessModes); }
static Stream<Arguments> accessModeProvider() { return Stream.of( // Arguments.of(EnumSet.noneOf(AccessMode.class), 0), // Arguments.of(EnumSet.of(AccessMode.READ), AccessConstants.R_OK), // Arguments.of(EnumSet.of(AccessMode.WRITE), AccessConstants.W_OK), // Arguments.of(EnumSet.of(AccessMode.EXECUTE), AccessConstants.X_OK), // Arguments.of(EnumSet.of(AccessMode.READ, AccessMode.WRITE), AccessConstants.R_OK | AccessConstants.W_OK), // Arguments.of(EnumSet.allOf(AccessMode.class), AccessConstants.R_OK | AccessConstants.W_OK | AccessConstants.X_OK | AccessConstants.F_OK) // ); }
/** * Add access to a directory iff it exists already * @param policy current policy to add permissions to * @param configurationName the configuration name associated with the path (for error messages only) * @param path the path itself * @param permissions set of file permissions to grant to the path */ static void addPathIfExists(Permissions policy, String configurationName, Path path, String permissions) { if (Files.isDirectory(path)) { // add each path twice: once for itself, again for files underneath it policy.add(new FilePermission(path.toString(), permissions)); policy.add(new FilePermission(path.toString() + path.getFileSystem().getSeparator() + "-", permissions)); try { path.getFileSystem().provider().checkAccess(path.toRealPath(), AccessMode.READ); } catch (IOException e) { throw new IllegalStateException("Unable to access '" + configurationName + "' (" + path + ")", e); } } }
private FileNode begin() throws IOException { final FileNode buffer; final Path entryFile = node.getPath(); Boolean exists = null; if (options.get(EXCLUSIVE) && (exists = exists(entryFile))) throw new FileAlreadyExistsException(node.toString()); if (options.get(CACHE)) { // This is obviously NOT properly isolated. if (TRUE.equals(exists) || null == exists && (exists = exists(entryFile))) { //if (!isWritable(entryFile)) throw new IOException(...) entryFile .getFileSystem() .provider() .checkAccess(entryFile, AccessMode.WRITE); } else { createFile(entryFile); } buffer = node.createIoBuffer(); } else { buffer = node; } if (options.get(CREATE_PARENTS) && !TRUE.equals(exists)) { final Path parentFile = entryFile.getParent(); if (null != parentFile) { try { createDirectories(parentFile); } catch (IOException ex) { // Workaround for bug in Oracle JDK 1.7.0_51: // A call to Files.createDirectories("C:\\") will fail on // Windows although it shouldn't. // Likewise, a call to Files.createDirectories("/") will // fail on Mac OS X although it shouldn't. // On Linux, it supposedly works however. if (!isDirectory(parentFile)) throw ex; } } } return buffer; }
@Test public void testMkvMustBeReadable() throws Exception { doThrow(new NoSuchFileException(null)).when(provider).checkAccess(mkv, AccessMode.READ); exception.expect(NoSuchFileException.class); muxer.start(); }
@Test public void testSrtMustBeReadable() throws Exception { doThrow(new NoSuchFileException(null)).when(provider).checkAccess(srt, AccessMode.READ); exception.expect(NoSuchFileException.class); muxer.start(); }
@Test public void testempDirMustBeWriteable() throws Exception { doThrow(new NoSuchFileException(null)).when(provider).checkAccess(tempDir, AccessMode.WRITE); exception.expect(NoSuchFileException.class); muxer.start(); }
@Test public void testIOExceptionInStartGoesToFailedState() throws Exception { // Given doThrow(new NoSuchFileException(null)).when(provider).checkAccess(tempDir, AccessMode.WRITE); Muxer muxer = Muxer.of(mkv, srt, tempDir); try { muxer.start(); fail("Must throw NoSuchFileException"); } catch (NoSuchFileException e) { // NOPMD: Ignored } // Then assertThat(muxer.state()).isEqualTo(State.FAILED); }
@Override public void checkAccess(Path file, AccessMode... modes) throws IOException { triggerEx(file, "checkAccess"); // hack if (modes.length == 0) { if (Files.exists(unwrap(file))) return; else throw new NoSuchFileException(file.toString()); } throw new RuntimeException("not implemented yet"); }
@Override public void checkAccess(Path path, AccessMode... modes) throws IOException { MCRPath mcrPath = MCRFileSystemUtils.checkPathAbsolute(path); MCRFilesystemNode node = resolvePath(mcrPath); if (node == null) { throw new NoSuchFileException(mcrPath.toString()); } if (node instanceof MCRDirectory) { checkDirectory((MCRDirectory) node, modes); } else { checkFile((MCRFile) node, modes); } }
private void checkDirectory(MCRDirectory rootDirectory, AccessMode... modes) throws AccessDeniedException { for (AccessMode mode : modes) { switch (mode) { case READ: case WRITE: case EXECUTE: break; default: throw new UnsupportedOperationException("Unsupported AccessMode: " + mode); } } }
private void checkFile(MCRFile file, AccessMode... modes) throws AccessDeniedException { for (AccessMode mode : modes) { switch (mode) { case READ: case WRITE: break; case EXECUTE: throw new AccessDeniedException(file.toPath().toString(), null, "Unsupported AccessMode: " + mode); default: throw new UnsupportedOperationException("Unsupported AccessMode: " + mode); } } }
@Override public void checkAccess(Path path, AccessMode... modes) throws IOException { BootJar jar = jar(path); if (jar == null) { throw new FileNotFoundException(L.l("{0} does not exist", path)); } }
@Override public void checkAccess(Path path, AccessMode... modes) throws IOException { URL url = getURL(path); if (url == null) { throw new IOException(L.l("{0} does not exist", path)); } }
@Override public void checkAccess(Path file, AccessMode... modes) throws IOException { if (modes.length == 0) { if (Files.exists(EncryptedFileSystem.dismantle(file))) return; else throw new NoSuchFileException(file.toString()); } // see // https://docs.oracle.com/javase/7/docs/api/java/nio/file/spi/FileSystemProvider.html#checkAccess%28java.nio.file.Path,%20java.nio.file.AccessMode...%29 throw new UnsupportedOperationException("not implemented"); }
/** * Creates a new instance. * * @param fs the wrapped file system * @param removedPaths paths that don't exist in this file system provider * @param addedPathTargets targets for additional paths that only exist in this file system provider * @param addedPathPermissions permissions for additional paths that only exist in this file system provider * @param exceptionPaths access to these files using these access modes should trigger an {@link IOException} */ TestFileSystemProvider(FileSystem fs, List< String > removedPaths, Map< String, String > addedPathTargets, Map< String, Permissions > addedPathPermissions, Map< String, Set< AccessMode > > exceptionPaths) { this.provider = fs.provider(); this.removedPaths = new ArrayList< Path >(); for (String removedPath : removedPaths) { this.removedPaths.add(fs.getPath(removedPath).toAbsolutePath()); } this.addedPathTargets = new HashMap<>(); for (Map.Entry< String, String > addedPath : addedPathTargets.entrySet()) { this.addedPathTargets.put(fs.getPath(addedPath.getKey()).toAbsolutePath(), fs.getPath(addedPath.getValue()) .toAbsolutePath()); } this.addedPathPermissions = new HashMap<>(); for (Map.Entry< String, Permissions > addedPathPermission : addedPathPermissions.entrySet()) { this.addedPathPermissions.put(fs.getPath(addedPathPermission.getKey()).toAbsolutePath(), addedPathPermission.getValue()); } this.exceptionPaths = new HashMap<>(); for (Map.Entry< String, Set< AccessMode > > entry : exceptionPaths.entrySet()) { this.exceptionPaths.put(fs.getPath(entry.getKey()).toAbsolutePath(), entry.getValue()); } }
private static AccessMode[] toAccessModes(Set< ? extends OpenOption > options) { boolean write = options.contains(StandardOpenOption.WRITE); boolean append = options.contains(StandardOpenOption.APPEND); List< AccessMode > modes = new ArrayList<>(); if (write || append) { modes.add(AccessMode.WRITE); } else { modes.add(AccessMode.READ); } return modes.toArray(new AccessMode[modes.size()]); }
/** {@inheritDoc} */ @Override public DirectoryStream< Path > newDirectoryStream(Path dir, Filter< ? super Path > filter) throws IOException { dir = ((TestPath) dir).unwrap(); checkIfRemoved(dir); checkPermissions(dir, true, AccessMode.READ); return provider.newDirectoryStream(dir, filter); }
/** {@inheritDoc} */ @Override public void createDirectory(Path dir, FileAttribute< ? >... attrs) throws IOException { dir = ((TestPath) dir).unwrap(); Path parent = dir.getParent(); if (parent != null) { checkIfRemoved(parent); checkPermissions(parent, true, AccessMode.WRITE); } provider.createDirectory(dir, attrs); }
/** {@inheritDoc} */ @Override public void delete(Path path) throws IOException { path = ((TestPath) path).unwrap(); checkIfRemoved(path); Path parent = path.getParent(); if (parent != null) { checkPermissions(parent, true, AccessMode.WRITE); } provider.delete(path); }
/** {@inheritDoc} */ @Override public void copy(Path source, Path target, CopyOption... options) throws IOException { source = ((TestPath) source).unwrap(); target = ((TestPath) target).unwrap(); checkIfRemoved(source); checkPermissions(source, true, AccessMode.READ); provider.copy(source, target, options); }
/** {@inheritDoc} */ @Override public void checkAccess(Path path, AccessMode... modes) throws IOException { path = ((TestPath) path).unwrap(); checkIfRemoved(path); boolean checked = checkPermissions(path, false, modes); if (!checked) { provider.checkAccess(path, modes); } }
private boolean checkPermissions(Path path, boolean checkExceptions, AccessMode... modes) throws AccessDeniedException, IOException { Permissions permissions = addedPathPermissions.get(path.toAbsolutePath()); boolean hasPermissions = permissions != null; if (hasPermissions) { for (AccessMode mode : modes) { switch (mode) { case READ: if (permissions != RWX && permissions != R_X && permissions != RW_ && permissions != R__) { throw new AccessDeniedException(path.toString()); } break; case WRITE: if (permissions != RWX && permissions != _WX && permissions != RW_ && permissions != _W_) { throw new AccessDeniedException(path.toString()); } break; case EXECUTE: if (permissions != RWX && permissions != _WX && permissions != R_X && permissions != __X) { throw new AccessDeniedException(path.toString()); } break; default: // impossible } } } if (checkExceptions) { checkExceptions(path, modes); } return hasPermissions; }
private void checkExceptions(Path path, AccessMode... modes) throws IOException { Set< AccessMode > errorModes = exceptionPaths.get(path.toAbsolutePath()); if (errorModes != null) { for (AccessMode mode : modes) { if (errorModes.contains(mode)) { throw new IOException(path.toString()); } } } }
/** * Simulates an {@link IOException} whenever the specified files are read from or written to. * * @param paths the paths of the files which are to trigger an {@link IOException} on read or write * @param mode the access mode that should trigger the {@link IOException} (read or write) * @return this test file system builder, ready for further customization */ private TestFS throwingException(String[] paths, AccessMode mode) { for (String path : paths) { Set< AccessMode > modes = exceptionPaths.get(path); if (modes == null) { modes = new HashSet<>(3); exceptionPaths.put(path, modes); } modes.add(mode); } return this; }