Improve VPN status reporting and recovery
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
import Foundation
|
||||
|
||||
/// One current file and one bounded archive. The owning process serializes writes.
|
||||
struct BoundedLog {
|
||||
let url: URL
|
||||
var maxBytes = 5 * 1024 * 1024
|
||||
|
||||
func append(_ line: String) throws {
|
||||
let files = FileManager.default
|
||||
try files.createDirectory(at: url.deletingLastPathComponent(), withIntermediateDirectories: true)
|
||||
if !files.fileExists(atPath: url.path) {
|
||||
guard files.createFile(atPath: url.path, contents: nil, attributes: [.posixPermissions: 0o600]) else {
|
||||
throw CocoaError(.fileWriteUnknown)
|
||||
}
|
||||
}
|
||||
try files.setAttributes([.posixPermissions: 0o600], ofItemAtPath: url.path)
|
||||
let handle = try FileHandle(forUpdating: url)
|
||||
defer { try? handle.close() }
|
||||
let size = try handle.seekToEnd()
|
||||
let data = Data(line.utf8).suffix(maxBytes)
|
||||
let archive = url.appendingPathExtension("1")
|
||||
var archiveSize: UInt64 = 0
|
||||
if files.fileExists(atPath: archive.path) {
|
||||
try files.setAttributes([.posixPermissions: 0o600], ofItemAtPath: archive.path)
|
||||
archiveSize = (try files.attributesOfItem(atPath: archive.path)[.size] as? NSNumber)?.uint64Value ?? 0
|
||||
}
|
||||
if size + UInt64(data.count) > UInt64(maxBytes) || archiveSize > UInt64(maxBytes) {
|
||||
try handle.seek(toOffset: size > UInt64(maxBytes) ? size - UInt64(maxBytes) : 0)
|
||||
let tail = try handle.read(upToCount: maxBytes) ?? Data()
|
||||
guard files.createFile(atPath: archive.path, contents: tail, attributes: [.posixPermissions: 0o600]) else {
|
||||
throw CocoaError(.fileWriteUnknown)
|
||||
}
|
||||
try handle.truncate(atOffset: 0)
|
||||
try handle.seek(toOffset: 0)
|
||||
}
|
||||
try handle.write(contentsOf: data)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user