252 lines
5.8 KiB
Go
252 lines
5.8 KiB
Go
/*
|
|
* ============================================================================
|
|
* Projekt.....: rs2322tcp
|
|
* Datei.......: internal/client/virtual_port_validation.go
|
|
* Copyright (C) 2026 Dieter Lang
|
|
*
|
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
*
|
|
* Beschreibung:
|
|
* Plattformneutrale Prüfung der in client.json definierten virtuellen Ports
|
|
* gegen die tatsächlich vorhandenen virtuellen Schnittstellen.
|
|
*
|
|
* Die Ermittlung der vorhandenen Ports erfolgt über die
|
|
* plattformabhängige Funktion existingVirtualPortLinks().
|
|
* ============================================================================
|
|
*/
|
|
package client
|
|
|
|
import (
|
|
"fmt"
|
|
"sort"
|
|
"strings"
|
|
|
|
"git.lang-dieter.de/rs2322tcp/internal/config"
|
|
)
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// Virtual port validation
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
// VirtualPortValidationResult contains the differences between configured
|
|
// and locally available virtual ports.
|
|
type VirtualPortValidationResult struct {
|
|
Missing []string
|
|
Extra []string
|
|
}
|
|
|
|
// compareVirtualPorts compares the configured virtual ports with the
|
|
// locally available virtual ports.
|
|
//
|
|
// Missing contains ports configured in client.json that are not available
|
|
// locally.
|
|
//
|
|
// Extra contains locally available ports that are not configured in
|
|
// client.json.
|
|
//
|
|
// The order of both input lists is irrelevant.
|
|
func compareVirtualPorts(
|
|
configured []string,
|
|
available []string,
|
|
) VirtualPortValidationResult {
|
|
configuredSet := make(map[string]struct{}, len(configured))
|
|
|
|
for _, port := range configured {
|
|
configuredSet[port] = struct{}{}
|
|
}
|
|
|
|
availableSet := make(map[string]struct{}, len(available))
|
|
|
|
for _, port := range available {
|
|
availableSet[port] = struct{}{}
|
|
}
|
|
|
|
result := VirtualPortValidationResult{
|
|
Missing: make([]string, 0),
|
|
Extra: make([]string, 0),
|
|
}
|
|
|
|
for port := range configuredSet {
|
|
if _, ok := availableSet[port]; ok {
|
|
continue
|
|
}
|
|
|
|
result.Missing = append(result.Missing, port)
|
|
}
|
|
|
|
for port := range availableSet {
|
|
if _, ok := configuredSet[port]; ok {
|
|
continue
|
|
}
|
|
|
|
result.Extra = append(result.Extra, port)
|
|
}
|
|
|
|
sort.Strings(result.Missing)
|
|
sort.Strings(result.Extra)
|
|
|
|
return result
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// Local virtual-port validation
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
// validateLocalVirtualPorts compares the virtual ports defined in
|
|
// client.json with the virtual ports currently available on the local
|
|
// computer.
|
|
//
|
|
// The detection of available ports is performed by the platform-specific
|
|
// existingVirtualPortLinks() implementation.
|
|
//
|
|
// A mismatch prevents the client from starting.
|
|
func validateLocalVirtualPorts(
|
|
cfg *config.ClientConfig,
|
|
) error {
|
|
if cfg == nil {
|
|
return fmt.Errorf("client configuration is nil")
|
|
}
|
|
|
|
configured := make(
|
|
[]string,
|
|
0,
|
|
len(cfg.VirtualPorts),
|
|
)
|
|
|
|
for _, virtualPort := range cfg.VirtualPorts {
|
|
configured = append(
|
|
configured,
|
|
virtualPort.Port,
|
|
)
|
|
}
|
|
|
|
available, err := existingVirtualPortLinks(
|
|
cfg.VirtualPortRange,
|
|
)
|
|
if err != nil {
|
|
return fmt.Errorf(
|
|
"prüfen der virtuellen Ports fehlgeschlagen: %w",
|
|
err,
|
|
)
|
|
}
|
|
|
|
result := compareVirtualPorts(
|
|
configured,
|
|
available,
|
|
)
|
|
|
|
if len(result.Missing) == 0 &&
|
|
len(result.Extra) == 0 {
|
|
return nil
|
|
}
|
|
|
|
var message strings.Builder
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// Missing ports
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
if len(result.Missing) > 0 &&
|
|
len(result.Extra) == 0 {
|
|
|
|
message.WriteString(
|
|
"Virtuelle Ports nicht eingerichtet",
|
|
)
|
|
|
|
message.WriteString(
|
|
"\n\nFolgende Ports sind in client.json " +
|
|
"eingetragen, aber auf diesem Rechner " +
|
|
"nicht eingerichtet:\n\n",
|
|
)
|
|
|
|
for _, port := range result.Missing {
|
|
message.WriteString(" ")
|
|
message.WriteString(port)
|
|
message.WriteByte('\n')
|
|
}
|
|
|
|
message.WriteString(
|
|
"\nBitte richten Sie diese virtuellen Ports " +
|
|
"entsprechend der Installationsanleitung ein.",
|
|
)
|
|
|
|
return fmt.Errorf(
|
|
"%s",
|
|
strings.TrimSpace(message.String()),
|
|
)
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// Extra ports
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
if len(result.Missing) == 0 &&
|
|
len(result.Extra) > 0 {
|
|
|
|
message.WriteString(
|
|
"Virtuelle Ports nicht konfiguriert",
|
|
)
|
|
|
|
message.WriteString(
|
|
"\n\nFolgende virtuelle Ports sind auf diesem " +
|
|
"Rechner eingerichtet, aber nicht in " +
|
|
"client.json eingetragen:\n\n",
|
|
)
|
|
|
|
for _, port := range result.Extra {
|
|
message.WriteString(" ")
|
|
message.WriteString(port)
|
|
message.WriteByte('\n')
|
|
}
|
|
|
|
message.WriteString(
|
|
"\nBitte ergänzen Sie die entsprechenden " +
|
|
"Einträge in client.json.",
|
|
)
|
|
|
|
return fmt.Errorf(
|
|
"%s",
|
|
strings.TrimSpace(message.String()),
|
|
)
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// Missing and extra ports
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
message.WriteString(
|
|
"Virtuelle Portkonfiguration stimmt nicht überein",
|
|
)
|
|
|
|
message.WriteString(
|
|
"\n\nIn client.json eingetragen, aber nicht " +
|
|
"eingerichtet:\n\n",
|
|
)
|
|
|
|
for _, port := range result.Missing {
|
|
message.WriteString(" ")
|
|
message.WriteString(port)
|
|
message.WriteByte('\n')
|
|
}
|
|
|
|
message.WriteString(
|
|
"\nEingerichtet, aber nicht in client.json " +
|
|
"eingetragen:\n\n",
|
|
)
|
|
|
|
for _, port := range result.Extra {
|
|
message.WriteString(" ")
|
|
message.WriteString(port)
|
|
message.WriteByte('\n')
|
|
}
|
|
|
|
message.WriteString(
|
|
"\nBitte korrigieren Sie die virtuelle " +
|
|
"Portkonfiguration.",
|
|
)
|
|
|
|
return fmt.Errorf(
|
|
"%s",
|
|
strings.TrimSpace(message.String()),
|
|
)
|
|
}
|