This repository has been archived by the owner on Mar 30, 2020. It is now read-only.
/
mac-host.rb
116 lines (96 loc) · 2.48 KB
/
mac-host.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
require 'socket'
module Ghost
class Host
ListCmd = "dscl localhost -list /Local/Default/Hosts 2>&1"
ReadCmd = "dscl localhost -read /Local/Default/Hosts/%s 2>&1"
CreateCmd = "dscl localhost -create /Local/Default/Hosts/%s IPAddress %s 2>&1"
DeleteCmd = "dscl localhost -delete /Local/Default/Hosts/%s 2>&1"
class << self
protected :new
def list
list = `#{ListCmd}`
list = list.split("\n")
list.collect { |host| Host.new(host.chomp) }
end
def add(host, ip = "127.0.0.1", force = false)
if find_by_host(host).nil? || force
unless ip[/^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})?$/]
ip = Socket.gethostbyname(ip)[3].bytes.to_a.join('.')
end
`#{CreateCmd % [host, ip]}`
flush!
find_by_host(host)
else
raise Ghost::RecordExists, "Can not overwrite existing record"
end
end
def find_by_host(host)
@hosts ||= {}
@hosts[host] ||= begin
output = `#{ReadCmd % host}`
if output =~ /eDSRecordNotFound/
nil
else
host = parse_host(output)
ip = parse_ip(output)
Host.new(host, ip)
end
end
end
def find_by_ip(ip)
nil
end
def empty!
list.each { |h| delete(h) }
nil
end
def delete(host)
`#{DeleteCmd % host.to_s}`
flush!
end
def delete_matching(pattern)
pattern = Regexp.escape(pattern)
hosts = list.select { |h| h.to_s.match(/#{pattern}/) }
hosts.each do |h|
delete(h)
end
flush! unless hosts.empty?
hosts
end
# Flushes the DNS Cache
def flush!
`dscacheutil -flushcache`
@hosts = {}
true
end
protected
def parse_host(output)
parse_value(output, 'RecordName')
end
def parse_ip(output)
parse_value(output, 'IPAddress')
end
def parse_value(output, key)
match = output.match(Regexp.new("^#{key}: (.*)$"))
match[1] unless match.nil?
end
end
def initialize(host, ip=nil)
@host = host
@ip = ip
end
def hostname
@host
end
alias :to_s :hostname
alias :host :hostname
alias :name :hostname
def ip
@ip ||= self.class.send(:parse_ip, dump)
end
private
def dump
@dump ||= `#{ReadCmd % hostname}`
end
end
end