diff --git a/TFM/App/TermindApp.swift b/TFM/App/TermindApp.swift index bac02e28..4ba37027 100644 --- a/TFM/App/TermindApp.swift +++ b/TFM/App/TermindApp.swift @@ -1,5 +1,4 @@ import AgentKitScrubber -import DeviceKit import SwiftData import SwiftUI import TermindApplication @@ -159,7 +158,7 @@ struct TermindApp: App { } fileprivate static var computerName: String { - Device.current.safeDescription + MacDeviceName.current } #if canImport(AppKit) diff --git a/TFM/Platform/MacDeviceName.swift b/TFM/Platform/MacDeviceName.swift new file mode 100644 index 00000000..79ea8782 --- /dev/null +++ b/TFM/Platform/MacDeviceName.swift @@ -0,0 +1,30 @@ +import Darwin +import DeviceKit +import Foundation + +enum MacDeviceName { + static var current: String { + resolved(kernelHostname: kernelHostname(), fallback: Device.current.safeDescription) + } + + static func resolved(kernelHostname: String?, fallback: String) -> String { + guard let kernelHostname else { return fallback } + let hostname = kernelHostname.trimmingCharacters(in: .whitespacesAndNewlines) + return hostname.isEmpty ? fallback : hostname + } + + static func kernelHostname() -> String? { + var size = 0 + guard sysctlbyname("kern.hostname", nil, &size, nil, 0) == 0, size > 0 else { + return nil + } + + var buffer = [CChar](repeating: 0, count: size) + guard sysctlbyname("kern.hostname", &buffer, &size, nil, 0) == 0 else { + return nil + } + + let utf8 = buffer.prefix { $0 != 0 }.map { UInt8(bitPattern: $0) } + return String(decoding: utf8, as: UTF8.self) + } +} diff --git a/TFMTests/MacDeviceNameTests.swift b/TFMTests/MacDeviceNameTests.swift new file mode 100644 index 00000000..707ebd9a --- /dev/null +++ b/TFMTests/MacDeviceNameTests.swift @@ -0,0 +1,31 @@ +import Foundation +import Testing + +@testable import Termind + +struct MacDeviceNameTests { + @Test + func kernelHostnameTakesPriorityOverFallback() { + let hostname = UUID().uuidString + #expect( + MacDeviceName.resolved( + kernelHostname: hostname, + fallback: "fallback" + ) == hostname + ) + } + + @Test + func unavailableOrEmptyKernelHostnameUsesFallback() { + let fallback = UUID().uuidString + #expect(MacDeviceName.resolved(kernelHostname: nil, fallback: fallback) == fallback) + #expect(MacDeviceName.resolved(kernelHostname: "", fallback: fallback) == fallback) + #expect(MacDeviceName.resolved(kernelHostname: " \n ", fallback: fallback) == fallback) + } + + @Test + func kernelHostnameIsReadable() throws { + let hostname = try #require(MacDeviceName.kernelHostname()) + #expect(!hostname.isEmpty) + } +}