mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2024-12-14 20:20:30 +00:00
Check the filesystem for isReadOnly (#1226)
This commit is contained in:
parent
b8fce1eecc
commit
47816805fb
@ -78,4 +78,15 @@ public interface IWritableMount extends IMount {
|
||||
default OptionalLong getCapacity() {
|
||||
return OptionalLong.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether a file with a given path is read-only or not.
|
||||
*
|
||||
* @param path A file path in normalised format, relative to the mount location. ie: "programs/myprograms".
|
||||
* @return If the file exists and is read-only.
|
||||
* @throws IOException If an error occurs when checking whether the file is read-only.
|
||||
*/
|
||||
default boolean isReadOnly(String path) throws IOException {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -143,6 +143,16 @@ public class FileMount implements IWritableMount {
|
||||
return file.exists() && file.isDirectory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReadOnly(String path) throws IOException {
|
||||
var file = getRealPath(path);
|
||||
while (true) {
|
||||
if (file.exists()) return !file.canWrite();
|
||||
if (file.equals(rootPath)) return false;
|
||||
file = file.getParentFile();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void list(String path, List<String> contents) throws IOException {
|
||||
if (!created()) {
|
||||
|
@ -94,6 +94,15 @@ public class FileSystemWrapperMount implements IFileSystem {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReadOnly(String path) throws IOException {
|
||||
try {
|
||||
return filesystem.isReadOnly(path);
|
||||
} catch (FileSystemException e) {
|
||||
throw new IOException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void list(String path, List<String> contents) throws IOException {
|
||||
try {
|
||||
|
@ -61,8 +61,12 @@ class MountWrapper {
|
||||
return writableMount == null ? OptionalLong.empty() : writableMount.getCapacity();
|
||||
}
|
||||
|
||||
public boolean isReadOnly(String path) {
|
||||
return writableMount == null;
|
||||
public boolean isReadOnly(String path) throws FileSystemException {
|
||||
try {
|
||||
return writableMount == null || writableMount.isReadOnly(path);
|
||||
} catch (IOException e) {
|
||||
throw localExceptionOf(path, e);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean exists(String path) throws FileSystemException {
|
||||
|
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
package dan200.computercraft.core.filesystem;
|
||||
|
||||
import com.google.common.io.MoreFiles;
|
||||
import com.google.common.io.RecursiveDeleteOption;
|
||||
import dan200.computercraft.api.filesystem.IWritableMount;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Assumptions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.attribute.PosixFileAttributeView;
|
||||
import java.nio.file.attribute.PosixFilePermission;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class FileMountTest {
|
||||
private static final long CAPACITY = 1_000_000;
|
||||
private final List<Path> cleanup = new ArrayList<>();
|
||||
|
||||
@AfterEach
|
||||
public void cleanup() throws IOException {
|
||||
for (var mount : cleanup) MoreFiles.deleteRecursively(mount, RecursiveDeleteOption.ALLOW_INSECURE);
|
||||
}
|
||||
|
||||
private Path createRoot() throws IOException {
|
||||
var path = Files.createTempDirectory("cctweaked-test");
|
||||
cleanup.add(path);
|
||||
return path;
|
||||
}
|
||||
|
||||
private IWritableMount getExisting(long capacity) throws IOException {
|
||||
return new FileMount(createRoot().toFile(), capacity);
|
||||
}
|
||||
|
||||
private IWritableMount getNotExisting(long capacity) throws IOException {
|
||||
return new FileMount(createRoot().resolve("mount").toFile(), capacity);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRootWritable() throws IOException {
|
||||
assertFalse(getExisting(CAPACITY).isReadOnly("/"));
|
||||
assertFalse(getNotExisting(CAPACITY).isReadOnly("/"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMissingDirWritable() throws IOException {
|
||||
assertFalse(getExisting(CAPACITY).isReadOnly("/foo/bar/baz/qux"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDirReadOnly() throws IOException {
|
||||
var root = createRoot();
|
||||
var mount = new FileMount(root.toFile(), CAPACITY);
|
||||
mount.makeDirectory("read-only");
|
||||
|
||||
var attributes = Files.getFileAttributeView(root.resolve("read-only"), PosixFileAttributeView.class);
|
||||
Assumptions.assumeTrue(attributes != null, "POSIX attributes are not available.");
|
||||
|
||||
assertFalse(mount.isReadOnly("read-only"), "Directory should not be read-only yet");
|
||||
attributes.setPermissions(Set.of(PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_EXECUTE));
|
||||
assertTrue(mount.isReadOnly("read-only"), "Directory should not be read-only yet");
|
||||
assertTrue(mount.isReadOnly("read-only/child"), "Child should be read-only");
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user