feat(fls): import the e-mail programs into the editor model
The e-mail client and server of every host come into the model (core: EmailClientConfiguration, EmailServerConfiguration, EmailMessage), from Java's view: - the server's accounts are those of /mailserver/konten.txt, as Java reads them at every simulation start; without the file those of the bean list, which Java would drop; - the client's account is that of /konten.txt; without it the first of an older file's kontoListe, which FILIUS 2.14 no longer reads; - messages are numbered per program in folder order, as Swift does; the sent folder's are sent; a date is taken only when the file gives one. Departures from Swift: accounts and messages stay where Swift drops what fails its checks; first and last name stay apart; a port that is no number is the default, with a warning. On the corpus the model matches Swift's on all 13 files; the one Swift error is named (it numbers a mailbox's messages as their received time and writes that into the konten.txt it rewrites). The Swift dump now carries the e-mail state, and the file system comparison leaves out only Swift's hidden state files (and the directories it makes for them) instead of all of /mail, /mailserver and /peer2peer. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -33,10 +33,10 @@
|
||||
// - a web server's files stay in /webserver (its document root), where Swift
|
||||
// moves them to /www; and no program state is written into a host's files
|
||||
// (Swift keeps Gnutella and e-mail state there as hidden JSON files).
|
||||
// - e-mail: see importEmail.ts;
|
||||
// - a DNS server's records are what Java's server answers from /dns/hosts
|
||||
// (see dnsHosts.ts); Swift reads the file its own way — tabs, comments,
|
||||
// "IN", names with a leading digit — and drops Java's duplicates.
|
||||
// Not here yet: e-mail accounts.
|
||||
|
||||
import {
|
||||
canonicalMacAddress,
|
||||
@@ -65,6 +65,8 @@ import {
|
||||
type DhcpClientConfiguration,
|
||||
type DhcpServerConfiguration,
|
||||
type DnsServerConfiguration,
|
||||
type EmailClientConfiguration,
|
||||
type EmailServerConfiguration,
|
||||
type EchoServerConfiguration,
|
||||
type GnutellaConfiguration,
|
||||
type InstallableProgram,
|
||||
@@ -92,6 +94,7 @@ import {
|
||||
type VirtualFileContent,
|
||||
} from '@mdg-filius/core';
|
||||
import { dnsRecordsOf, javaHostsFileContent, readDnsHosts } from './dnsHosts.js';
|
||||
import { emailClientConfiguration, emailServerConfiguration } from './importEmail.js';
|
||||
import type { FlsApplicationClass, FlsFileTree, FlsFirewall } from './systemSoftware.js';
|
||||
import type { FlsDocumentationItem, FlsInterface, FlsNode, FlsNodeClass, FlsTopology } from './topology.js';
|
||||
|
||||
@@ -119,6 +122,8 @@ export interface ImportedProject {
|
||||
webServerConfigurations: Map<Id, WebServerConfiguration>;
|
||||
gnutellaConfigurations: Map<Id, GnutellaConfiguration>;
|
||||
dnsServerConfigurations: Map<Id, DnsServerConfiguration>;
|
||||
emailClientConfigurations: Map<Id, EmailClientConfiguration>;
|
||||
emailServerConfigurations: Map<Id, EmailServerConfiguration>;
|
||||
echoServerConfigurations: Map<Id, EchoServerConfiguration>;
|
||||
simpleClientConfigurations: Map<Id, SimpleClientConfiguration>;
|
||||
/** In render order: rectangles below text, then by order. */
|
||||
@@ -162,6 +167,8 @@ export function importProject(topology: FlsTopology, newId: () => Id): ImportedP
|
||||
webServerConfigurations: new Map(),
|
||||
gnutellaConfigurations: new Map(),
|
||||
dnsServerConfigurations: new Map(),
|
||||
emailClientConfigurations: new Map(),
|
||||
emailServerConfigurations: new Map(),
|
||||
echoServerConfigurations: new Map(),
|
||||
simpleClientConfigurations: new Map(),
|
||||
};
|
||||
@@ -369,6 +376,8 @@ type SystemConfigurations = Pick<
|
||||
| 'webServerConfigurations'
|
||||
| 'gnutellaConfigurations'
|
||||
| 'dnsServerConfigurations'
|
||||
| 'emailClientConfigurations'
|
||||
| 'emailServerConfigurations'
|
||||
| 'echoServerConfigurations'
|
||||
| 'simpleClientConfigurations'
|
||||
>;
|
||||
@@ -393,6 +402,10 @@ export const PROGRAM_OF_CLASS: Readonly<Record<FlsApplicationClass, InstallableP
|
||||
/** The web server's document root: where Java keeps its files. */
|
||||
export const JAVA_WEB_ROOT = '/webserver';
|
||||
|
||||
function warnAt(node: TopologyNode, warnings: string[]): (message: string) => void {
|
||||
return (message) => warnings.push(`node '${node.displayName}': ${message}`);
|
||||
}
|
||||
|
||||
/** The program parts of Swift's finalizeCurrentNodeCandidate, for a PC or notebook. */
|
||||
function registerPrograms(source: FlsNode, node: TopologyNode, system: SystemConfigurations, warnings: string[]): void {
|
||||
const installed = new Set<InstallableProgram>();
|
||||
@@ -420,9 +433,7 @@ function registerPrograms(source: FlsNode, node: TopologyNode, system: SystemCon
|
||||
const primary = trimmedOrEmpty(source.interfaces[0]?.ip);
|
||||
const forwarding = recursive && forwarder !== '' && forwarder !== primary;
|
||||
const hosts = javaHostsFileContent(source.system.fileSystem);
|
||||
const records = dnsRecordsOf(readDnsHosts(hosts ?? ''), (message) =>
|
||||
warnings.push(`node '${node.displayName}': ${message}`),
|
||||
);
|
||||
const records = dnsRecordsOf(readDnsHosts(hosts ?? ''), warnAt(node, warnings));
|
||||
system.dnsServerConfigurations.set(
|
||||
node.id,
|
||||
forwarding
|
||||
@@ -431,6 +442,12 @@ function registerPrograms(source: FlsNode, node: TopologyNode, system: SystemCon
|
||||
);
|
||||
break;
|
||||
}
|
||||
case 'emailClient':
|
||||
system.emailClientConfigurations.set(node.id, emailClientConfiguration(application, warnAt(node, warnings)));
|
||||
break;
|
||||
case 'emailServer':
|
||||
system.emailServerConfigurations.set(node.id, emailServerConfiguration(application, warnAt(node, warnings)));
|
||||
break;
|
||||
case 'firewall':
|
||||
if (application.firewall !== undefined) {
|
||||
system.firewallConfigurationsByNodeId.set(node.id, firewallConfigurationOf(application.firewall, `node '${node.displayName}'`, warnings));
|
||||
|
||||
Reference in New Issue
Block a user