feat(fls): file systems of PCs and notebooks as Java loads them

readSystemSoftware reads a host's file system: Java's tree of
DefaultMutableTreeNodes, directories named by their user object, files
as Datei (by setters or the three-argument constructor), rooted at
arbeitsVerzeichnis (up to 1.10) or root. All 23 corpus files match Java,
every file compared by name, type and the SHA-256 of its content.

Routers and home routers have files in Java too, but their constructor
makes them from templates (the start page of the firewall's web
interface); they are not in the file and not claimed here.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-29 21:14:01 +00:00
co-authored by Claude Opus 5.5
parent cf47cf8f9d
commit 51a83ea68d
6 changed files with 2936 additions and 5 deletions
+4 -1
View File
@@ -27,7 +27,10 @@ virtuellen Bildschirm statt „headless".
Schnittstellen, bei Rechner/Notebook `useIPAsName`/`useMACAsName`), unter
`system` SSID, Lernzeit des Switches, RIP, manuelle Routen, die Firewall
von Router und Heimrouter, DHCP-Client und -Server, die statische
NAT-Tabelle des Heimrouters und die Verbindung eines Modems; Kabel (Enden als Gerät/Schnittstelle),
NAT-Tabelle des Heimrouters, die Verbindung eines Modems und das
Dateisystem (Inhalte als Länge und SHA-256, damit die Referenz klein
bleibt; die Dateien von Router und Heimrouter erzeugt Javas Konstruktor aus
eigenen Vorlagen, sie stehen nicht in der Datei); Kabel (Enden als Gerät/Schnittstelle),
Doku-Elemente.
Systemsoftware, Dateisysteme und Anwendungen folgen schrittweise.
+40
View File
@@ -19,6 +19,7 @@ import filius.software.dhcp.DHCPServer;
import filius.software.firewall.Firewall;
import filius.software.firewall.FirewallRule;
import filius.software.system.Betriebssystem;
import filius.software.system.Datei;
import filius.software.system.GatewayFirmware;
import filius.software.system.InternetKnotenBetriebssystem;
import filius.software.system.ModemFirmware;
@@ -237,6 +238,7 @@ public class FlsOracle {
}
}
json.put("manualRoutes", routes);
json.put("fileSystem", system.getDateisystem() == null ? null : fileTree(system.getDateisystem().getRoot()));
json.put("dhcpClient", system.isDHCPKonfiguration());
DHCPServer server = system.getDHCPServer();
if (server != null) {
@@ -285,6 +287,44 @@ public class FlsOracle {
return json;
}
/**
* A file system tree: a directory is a node whose user object is its name,
* a file one whose user object is a Datei. Contents as SHA-256 and length
* of their UTF-8 bytes, to keep the reference small.
*/
static Map<String, Object> fileTree(javax.swing.tree.DefaultMutableTreeNode node) {
Map<String, Object> json = new LinkedHashMap<>();
Object user = node.getUserObject();
if (user instanceof Datei file) {
json.put("file", file.getName());
json.put("type", file.getDateiTyp());
String content = file.getDateiInhalt();
json.put("length", content == null ? null : content.length());
json.put("sha256", content == null ? null : sha256(content));
} else if (user == null || user instanceof String) {
json.put("directory", user);
} else {
json.put("userObject", user.getClass().getName());
}
List<Object> children = new ArrayList<>();
for (int index = 0; index < node.getChildCount(); index++) {
children.add(fileTree((javax.swing.tree.DefaultMutableTreeNode) node.getChildAt(index)));
}
json.put("children", children);
return json;
}
static String sha256(String text) {
try {
byte[] digest = java.security.MessageDigest.getInstance("SHA-256").digest(text.getBytes(StandardCharsets.UTF_8));
StringBuilder hex = new StringBuilder();
for (byte value : digest) hex.append(String.format("%02x", value));
return hex.toString();
} catch (java.security.NoSuchAlgorithmException error) {
throw new IllegalStateException(error);
}
}
/** Just enough JSON: maps, lists, strings, numbers, booleans, null. */
static final class Json {
static String write(Object value, String indent) {