Skip to content

Commit 6d8703b

Browse files
committed
feat: add verification logging for block/unblock and fix mDNSResponder exact-match pid lookup
1 parent 835ec09 commit 6d8703b

1 file changed

Lines changed: 59 additions & 6 deletions

File tree

TomeHelper/HostsEditor.swift

Lines changed: 59 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ class HostsEditor {
1414
var block = "\n\(blockMarkerStart)\n"
1515
for domain in unique {
1616
block += "0.0.0.0 \(domain)\n"
17-
// also block www. variant if not already present
1817
if !domain.hasPrefix("www.") {
1918
block += "0.0.0.0 www.\(domain)\n"
2019
}
@@ -23,17 +22,68 @@ class HostsEditor {
2322
content += block
2423
}
2524

26-
try? content.write(toFile: hostsPath, atomically: true, encoding: .utf8)
25+
do {
26+
try content.write(toFile: hostsPath, atomically: true, encoding: .utf8)
27+
} catch {
28+
log("ERROR: failed to write /etc/hosts during block: \(error)")
29+
return
30+
}
31+
2732
flushDNSCache()
33+
verifyBlock(expectedDomains: domains)
2834
}
2935

3036
func removeAllBlocks() {
3137
var content = (try? String(contentsOfFile: hostsPath, encoding: .utf8)) ?? ""
3238
content = removeBlockSection(from: content)
33-
try? content.write(toFile: hostsPath, atomically: true, encoding: .utf8)
39+
40+
do {
41+
try content.write(toFile: hostsPath, atomically: true, encoding: .utf8)
42+
} catch {
43+
log("ERROR: failed to write /etc/hosts during unblock: \(error)")
44+
return
45+
}
46+
3447
flushDNSCache()
48+
verifyUnblock()
49+
}
50+
51+
// MARK: - Verification
52+
53+
private func verifyBlock(expectedDomains: [String]) {
54+
guard let current = try? String(contentsOfFile: hostsPath, encoding: .utf8) else {
55+
log("VERIFY ERROR: could not re-read /etc/hosts after block")
56+
return
57+
}
58+
guard current.contains(blockMarkerStart), current.contains(blockMarkerEnd) else {
59+
log("VERIFY ERROR: tome-block markers missing from /etc/hosts after block")
60+
return
61+
}
62+
// spot-check first 3 domains
63+
let sample = Array(expectedDomains.prefix(3))
64+
for domain in sample {
65+
if !current.contains("0.0.0.0 \(domain)") {
66+
log("VERIFY ERROR: domain \(domain) not found in /etc/hosts after block")
67+
return
68+
}
69+
}
70+
log("VERIFY OK: \(expectedDomains.count) domain(s) confirmed in /etc/hosts")
3571
}
3672

73+
private func verifyUnblock() {
74+
guard let current = try? String(contentsOfFile: hostsPath, encoding: .utf8) else {
75+
log("VERIFY ERROR: could not re-read /etc/hosts after unblock")
76+
return
77+
}
78+
if current.contains(blockMarkerStart) || current.contains(blockMarkerEnd) {
79+
log("VERIFY ERROR: tome-block markers still present in /etc/hosts after unblock")
80+
return
81+
}
82+
log("VERIFY OK: /etc/hosts clean after unblock")
83+
}
84+
85+
// MARK: - Helpers
86+
3787
private func removeBlockSection(from content: String) -> String {
3888
var result = ""
3989
var inBlock = false
@@ -50,7 +100,6 @@ class HostsEditor {
50100
result += line + "\n"
51101
}
52102
}
53-
// trim trailing newlines added by section removal, preserve one
54103
return result.trimmingCharacters(in: .newlines) + "\n"
55104
}
56105

@@ -61,17 +110,21 @@ class HostsEditor {
61110
try? task.run()
62111
task.waitUntilExit()
63112

113+
guard let pid = mDNSResponderPID() else {
114+
log("WARN: could not find mDNSResponder PID — DNS cache not flushed via HUP")
115+
return
116+
}
64117
let task2 = Process()
65118
task2.launchPath = "/bin/kill"
66-
task2.arguments = ["-HUP", String(mDNSResponderPID() ?? 0)]
119+
task2.arguments = ["-HUP", String(pid)]
67120
try? task2.run()
68121
task2.waitUntilExit()
69122
}
70123

71124
private func mDNSResponderPID() -> Int32? {
72125
let task = Process()
73126
task.launchPath = "/bin/pgrep"
74-
task.arguments = ["mDNSResponder"]
127+
task.arguments = ["-x", "mDNSResponder"] // -x: exact match, avoids multi-match
75128
let pipe = Pipe()
76129
task.standardOutput = pipe
77130
try? task.run()

0 commit comments

Comments
 (0)