feat(fls): Java's view of the e-mail programs
The Java view now reads what FILIUS 2.14 keeps for its e-mail programs: the server's domain, switch and bean accounts with their mailboxes, and the accounts of /mailserver/konten.txt, which Java reads at every simulation start and which so win over the bean list; the client's three folders and address book, and its account from /konten.txt (no bean holds it). javaEmail.ts ports the bean setters and both file readers (stringZuListeBenutzerkonten, EmailKonto(String)); javaString.ts Java's trim, split and StringTokenizer; javaFileSystem.ts the file lookup, now shared with the DNS server, with the four non-ASCII units Java's equalsIgnoreCase also takes for an ASCII letter (measured over the BMP). Checked against Java on the corpus (the oracle dumps the e-mail state) and on 43 account files read by EmailServer.kontenLaden and EmailAnwendung.laden (EmailFileCases). Found: older files keep recipients as strings in the typed lists; a getter copy of the sender is filled and set back; one short server line makes Java throw for the whole file; a message with an empty text is lost on reading; a broken last client line empties the account. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
// Runs FILIUS's own readers of the e-mail account files on every case of a
|
||||
// list: EmailServer.kontenLaden on /mailserver/konten.txt ("server") and
|
||||
// EmailAnwendung.laden on /konten.txt ("client"). Writes the accounts Java
|
||||
// ends up with — the reference for packages/fls/src/javaEmail.ts. One case
|
||||
// per line: a whole file, ASCII with Java-style unicode escapes (backslash,
|
||||
// u, four hex digits).
|
||||
//
|
||||
// Usage: java -cp filius.jar:lib/*:classes EmailFileCases server|client <cases txt> <output json>
|
||||
|
||||
import filius.hardware.knoten.Rechner;
|
||||
import filius.software.email.EmailAnwendung;
|
||||
import filius.software.email.EmailKonto;
|
||||
import filius.software.email.EmailServer;
|
||||
import filius.software.system.Datei;
|
||||
import filius.software.system.Dateisystem;
|
||||
import filius.software.system.InternetKnotenBetriebssystem;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class EmailFileCases {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
boolean server = args[0].equals("server");
|
||||
List<Object> result = new ArrayList<>();
|
||||
for (String line : Files.readAllLines(Path.of(args[1]), StandardCharsets.US_ASCII)) {
|
||||
InternetKnotenBetriebssystem system = (InternetKnotenBetriebssystem) new Rechner().getSystemSoftware();
|
||||
Dateisystem fileSystem = system.getDateisystem();
|
||||
Datei file = new Datei();
|
||||
file.setName("konten.txt");
|
||||
file.setDateiInhalt(IpCheckCases.unescape(line));
|
||||
Object accounts;
|
||||
try {
|
||||
if (server) {
|
||||
EmailServer mail = new EmailServer();
|
||||
mail.setSystemSoftware(system);
|
||||
fileSystem.speicherDatei(fileSystem.holeRootPfad() + Dateisystem.FILE_SEPARATOR + "mailserver", file);
|
||||
mail.kontenLaden();
|
||||
accounts = FlsOracle.emailAccounts(mail.getListeBenutzerkonten());
|
||||
} else {
|
||||
EmailAnwendung mail = new EmailAnwendung();
|
||||
mail.setSystemSoftware(system);
|
||||
fileSystem.speicherDatei(fileSystem.getRoot(), file);
|
||||
mail.laden();
|
||||
Map<String, EmailKonto> konten = mail.holeKontoListe();
|
||||
accounts = konten.isEmpty() ? null : FlsOracle.emailAccounts(new ArrayList<>(konten.values())).get(0);
|
||||
}
|
||||
} catch (RuntimeException error) {
|
||||
accounts = "!" + error.getClass().getSimpleName();
|
||||
}
|
||||
result.add(Arrays.asList(line, accounts));
|
||||
}
|
||||
try (FileOutputStream out = new FileOutputStream(args[2])) {
|
||||
out.write((FlsOracle.Json.write(result, "") + "\n").getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
System.out.println("email " + args[0] + " cases: " + result.size());
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,12 @@ import filius.software.clientserver.ServerAnwendung;
|
||||
import filius.software.dateiaustausch.PeerToPeerAnwendung;
|
||||
import filius.software.dhcp.DHCPServer;
|
||||
import filius.software.dns.DNSServer;
|
||||
import filius.software.email.AddressEntry;
|
||||
import filius.software.email.Email;
|
||||
import filius.software.email.EmailAnwendung;
|
||||
import filius.software.email.EmailKonto;
|
||||
import filius.software.email.EmailServer;
|
||||
import filius.software.email.Kontakt;
|
||||
import filius.software.www.WebServer;
|
||||
import filius.software.firewall.Firewall;
|
||||
import filius.software.firewall.FirewallRule;
|
||||
@@ -296,8 +302,11 @@ public class FlsOracle {
|
||||
|
||||
/**
|
||||
* The installed applications of a PC or notebook, by key: the class, and
|
||||
* the settings the topology layer reads. E-mail accounts and messages are
|
||||
* a later layer.
|
||||
* the settings the topology layer reads. E-mail: the server's accounts as
|
||||
* the file's bean list has them and as kontenLaden() reads them from
|
||||
* /mailserver/konten.txt (what Java uses from the start of a simulation);
|
||||
* the client's folders and address book, and the account laden() reads
|
||||
* from /konten.txt when its window opens.
|
||||
*/
|
||||
static List<Object> applications(InternetKnotenBetriebssystem system) {
|
||||
List<Object> result = new ArrayList<>();
|
||||
@@ -318,6 +327,41 @@ public class FlsOracle {
|
||||
if (application instanceof DNSServer dns) json.put("recursiveResolutionEnabled", dns.isRecursiveResolutionEnabled());
|
||||
if (application instanceof WebServer web) json.put("useVHost", web.isUseVHost());
|
||||
if (application instanceof PeerToPeerAnwendung peer) json.put("maxTeilnehmerZahl", peer.getMaxTeilnehmerZahl());
|
||||
if (application instanceof EmailServer mail) {
|
||||
json.put("aktiv", mail.isAktiv());
|
||||
json.put("mailDomain", mail.getMailDomain());
|
||||
json.put("beanAccounts", emailAccounts(mail.getListeBenutzerkonten()));
|
||||
boolean hasFile = system.getDateisystem().holeDatei("/mailserver/konten.txt") != null;
|
||||
Object fileAccounts = null;
|
||||
if (hasFile) {
|
||||
try {
|
||||
mail.kontenLaden();
|
||||
fileAccounts = emailAccounts(mail.getListeBenutzerkonten());
|
||||
} catch (RuntimeException error) {
|
||||
fileAccounts = "!" + error.getClass().getSimpleName();
|
||||
}
|
||||
}
|
||||
json.put("fileAccounts", fileAccounts);
|
||||
}
|
||||
if (application instanceof EmailAnwendung mail) {
|
||||
json.put("received", emails(mail.getEmpfangeneNachrichten()));
|
||||
json.put("sent", emails(mail.getGesendeteNachrichten()));
|
||||
json.put("drafts", emails(mail.getErstellteNachrichten()));
|
||||
List<Object> contacts = new ArrayList<>();
|
||||
for (Kontakt contact : mail.getAdressbuch()) {
|
||||
contacts.add(Arrays.asList(contact.getName(), contact.getVorname(), contact.getStrasse(),
|
||||
contact.getHausnr(), contact.getPlz(), contact.getWohnort(), contact.getEmail(),
|
||||
contact.getTelefon()));
|
||||
}
|
||||
json.put("addressBook", contacts);
|
||||
try {
|
||||
mail.laden();
|
||||
Map<String, EmailKonto> accounts = mail.holeKontoListe();
|
||||
json.put("fileAccount", accounts.isEmpty() ? null : emailAccounts(new ArrayList<>(accounts.values())).get(0));
|
||||
} catch (RuntimeException error) {
|
||||
json.put("fileAccount", "!" + error.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
if (application instanceof Firewall firewall) {
|
||||
json.put("activated", firewall.isActivated());
|
||||
json.put("defaultPolicy", (int) firewall.getDefaultPolicy());
|
||||
@@ -331,6 +375,61 @@ public class FlsOracle {
|
||||
return result;
|
||||
}
|
||||
|
||||
static List<Object> emailAccounts(List<EmailKonto> accounts) {
|
||||
List<Object> result = new ArrayList<>();
|
||||
for (EmailKonto account : accounts) {
|
||||
Map<String, Object> json = new LinkedHashMap<>();
|
||||
json.put("benutzername", account.getBenutzername());
|
||||
json.put("passwort", account.getPasswort());
|
||||
json.put("nachname", account.getNachname());
|
||||
json.put("vorname", account.getVorname());
|
||||
json.put("emailAdresse", account.getEmailAdresse());
|
||||
json.put("pop3server", account.getPop3server());
|
||||
json.put("pop3port", account.getPop3port());
|
||||
json.put("smtpserver", account.getSmtpserver());
|
||||
json.put("smtpport", account.getSmtpport());
|
||||
json.put("nachrichten", emails(account.getNachrichten()));
|
||||
result.add(json);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static List<Object> emails(List<Email> emails) {
|
||||
List<Object> result = new ArrayList<>();
|
||||
for (Email email : emails) {
|
||||
Map<String, Object> json = new LinkedHashMap<>();
|
||||
json.put("absender", address(email.getAbsender()));
|
||||
json.put("empfaenger", addresses(email.getEmpfaenger()));
|
||||
json.put("cc", addresses(email.getCc()));
|
||||
json.put("bcc", addresses(email.getBcc()));
|
||||
json.put("betreff", email.getBetreff());
|
||||
json.put("text", email.getText());
|
||||
json.put("dateReceived", email.getDateReceived());
|
||||
json.put("neu", email.getNeu());
|
||||
json.put("delete", email.getDelete());
|
||||
json.put("versendet", email.isVersendet());
|
||||
result.add(json);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Older files keep recipients as strings: the list is typed, but the
|
||||
* decoder does not check, so an element may be a String.
|
||||
*/
|
||||
static List<Object> addresses(List<AddressEntry> entries) {
|
||||
List<Object> result = new ArrayList<>();
|
||||
for (Object entry : entries) {
|
||||
if (entry == null) result.add(null);
|
||||
else result.add(entry instanceof AddressEntry address ? address(address) : Arrays.asList("string", entry.toString()));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static List<Object> address(AddressEntry entry) {
|
||||
return entry == null ? null : Arrays.asList(entry.getName(), entry.getMailAddress());
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
||||
Reference in New Issue
Block a user