Native macOS agent that keeps the office VPN and the NAS shares working without the shell wrapper it replaces. - VPN: full port of the `ovpn` script — host-route pinning, gateway discovery via networksetup, tunnel liveness by address plus pushed route, startup grace, restart of a wedged daemon. Root steps are batched into one system authorization prompt. - SMB: mounts via NetFS, discovers shares from the server, detects mounts event-driven through NSWorkspace, matches the host by resolved alias so externally created mounts are recognised. - Credentials never pass through the process: the VPN auth file is written by `security` straight to disk, and the password is stored via SecItemAdd rather than a command line visible in ps. - UI: status window, settings editor, ⌘+/⌘− zoom that re-lays out rather than scaling a bitmap. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
34 lines
1.2 KiB
Swift
34 lines
1.2 KiB
Swift
import Foundation
|
|
|
|
/// Appends to ~/Library/Logs/CampusNAS.log.
|
|
///
|
|
/// NSLog output from an ad-hoc signed bundle does not reliably reach the
|
|
/// unified log, which made real errors invisible while debugging notification
|
|
/// delivery. A plain file is boring and always readable.
|
|
enum Log {
|
|
static let fileURL = URL(fileURLWithPath: NSHomeDirectory())
|
|
.appendingPathComponent("Library/Logs/CampusNAS.log")
|
|
|
|
private static let queue = DispatchQueue(label: "campusnas.log")
|
|
private static let formatter: DateFormatter = {
|
|
let f = DateFormatter()
|
|
f.dateFormat = "yyyy-MM-dd HH:mm:ss"
|
|
return f
|
|
}()
|
|
|
|
static func write(_ message: String) {
|
|
NSLog("campusnas-monitor: %@", message)
|
|
let line = "\(formatter.string(from: Date())) \(message)\n"
|
|
queue.async {
|
|
guard let data = line.data(using: .utf8) else { return }
|
|
if let handle = try? FileHandle(forWritingTo: fileURL) {
|
|
defer { try? handle.close() }
|
|
_ = try? handle.seekToEnd()
|
|
try? handle.write(contentsOf: data)
|
|
} else {
|
|
try? data.write(to: fileURL)
|
|
}
|
|
}
|
|
}
|
|
}
|