dyndyndong 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/bin/dyndyndong +72 -5
- data/lib/dyndyndong/services.rb +1 -3
- data/lib/dyndyndong/services/dyndns.rb +4 -83
- data/lib/dyndyndong/services/generic.rb +132 -0
- data/lib/dyndyndong/services/no-ip.rb +2 -13
- data/lib/dyndyndong/version.rb +1 -1
- metadata +3 -2
data/bin/dyndyndong
CHANGED
@@ -40,14 +40,26 @@ USAGE: #{$0} [-d|-h|-1] [-c <config file>] [-D <delay>] [-s <service> <service a
|
|
40
40
|
-s|--service Start to parse a service, no defaults, you have to choose between:
|
41
41
|
- afraid For freedns.afraid.org
|
42
42
|
AVAILABLE ARGUMENTS:
|
43
|
-
-H
|
44
|
-
- dyndns
|
43
|
+
-H|--host Set a single host or more hosts separated with ',' (comma), it can be repeated
|
44
|
+
- dyndns For dyndns.com
|
45
|
+
AVAILABLE ARGUMENTS:
|
46
|
+
-u|--username Set username for login, it can't be repeated
|
47
|
+
-p|--password Set password for login, it can't be repeated
|
48
|
+
-H|--host Set a single host or more hosts separated with ',' (comma), it can be repeated
|
49
|
+
-o|--offline Set a single host or more hosts separated with ',' (comma) to make offline, it
|
50
|
+
can be repeated
|
51
|
+
- no-ip For no-ip-com
|
45
52
|
AVAILABLE ARGUMENTS:
|
46
53
|
-u|--username Set username for login, it can't be repeated
|
47
54
|
-p|--password Set password for login, it can't be repeated
|
48
55
|
-H|--host Set a single host or more hosts separated with ',' (comma), it can be repeated
|
49
56
|
-o|--offline Set a single host or more hosts separated with ',' (comma) to make offline, it
|
50
57
|
can be repeated
|
58
|
+
- zoneedit For zoneedit.com
|
59
|
+
AVAILABLE ARGUMENTS:
|
60
|
+
-u|--username Set username for login, it can't be repeated
|
61
|
+
-p|--password Set password for login, it can't be repeated
|
62
|
+
-H|--host Set a single host or more hosts separated with ',' (comma), it can be repeated
|
51
63
|
Parsing of services' arguments stop when an unrelated argument is given.
|
52
64
|
HELP
|
53
65
|
exit 0
|
@@ -114,7 +126,7 @@ while i < ARGV.size
|
|
114
126
|
end
|
115
127
|
|
116
128
|
case service
|
117
|
-
when 'dyndns'
|
129
|
+
when 'dyndns', 'no-ip'
|
118
130
|
srv = {:hosts => [], :offline => []}
|
119
131
|
while (i += 1) < ARGV.size
|
120
132
|
parsed = true
|
@@ -154,6 +166,40 @@ while i < ARGV.size
|
|
154
166
|
end
|
155
167
|
srv[:hosts].flatten!
|
156
168
|
srv[:offline].flatten!
|
169
|
+
when 'zoneedit'
|
170
|
+
srv = {:hosts => []}
|
171
|
+
while (i += 1) < ARGV.size
|
172
|
+
parsed = true
|
173
|
+
case ARGV[i]
|
174
|
+
when /^-u/, '--username'
|
175
|
+
die "Can't add more than one username" if srv[:username]
|
176
|
+
|
177
|
+
if %w{-u --username}.include?(ARGV[1])
|
178
|
+
srv[:username] = ARGV[i += 1]
|
179
|
+
else
|
180
|
+
srv[:username] = ARGV[i].gsub(/^-u/, '')
|
181
|
+
end
|
182
|
+
when /^-p/, '--password'
|
183
|
+
die "Can't add more than one password" if srv[:password]
|
184
|
+
|
185
|
+
if %w{-p --password}.include?(ARGV[1])
|
186
|
+
srv[:password] = ARGV[i += 1]
|
187
|
+
else
|
188
|
+
srv[:password] = ARGV[i].gsub(/^-p/, '')
|
189
|
+
end
|
190
|
+
when /^-H/, '--host'
|
191
|
+
if %w{-H --host}.include?(ARGV[i])
|
192
|
+
srv[:hosts] << ARGV[i += 1].split(',')
|
193
|
+
else
|
194
|
+
srv[:hosts] << ARGV[i].gsub(/^-H/, '').split(',')
|
195
|
+
end
|
196
|
+
else
|
197
|
+
parsed = false
|
198
|
+
break
|
199
|
+
end
|
200
|
+
end
|
201
|
+
srv[:hosts].flatten!
|
202
|
+
srv[:offline].flatten!
|
157
203
|
when 'afraid'
|
158
204
|
srv = []
|
159
205
|
|
@@ -180,10 +226,10 @@ while i < ARGV.size
|
|
180
226
|
parsed = true
|
181
227
|
|
182
228
|
case service
|
183
|
-
when 'dyndns'
|
184
|
-
SERVICES[service.to_sym] << srv
|
185
229
|
when 'afraid'
|
186
230
|
SERVICES[service.to_sym] += srv
|
231
|
+
else
|
232
|
+
SERVICES[service.to_sym] << srv
|
187
233
|
end
|
188
234
|
end
|
189
235
|
|
@@ -220,6 +266,27 @@ if SERVICES != {:dyndns=>[],:afraid=>[]}
|
|
220
266
|
die "Respect the syntax of afraid please."
|
221
267
|
end
|
222
268
|
}
|
269
|
+
|
270
|
+
SERVICES[:zoneedit],each {|zoneedit|
|
271
|
+
z = DynDynDong::ZoneEdit.new
|
272
|
+
z.username = zoneedit[:username]
|
273
|
+
z.password = zoneedit[:password]
|
274
|
+
zoneedit[:hosts].each {|host|
|
275
|
+
z.host host
|
276
|
+
}
|
277
|
+
}
|
278
|
+
|
279
|
+
SERVICES[:'no-ip'].each {|noip|
|
280
|
+
n = DynDynDong::NoIp.new
|
281
|
+
n.username = noip[:username]
|
282
|
+
n.password = noip[:password]
|
283
|
+
noip[:hosts].each {|host|
|
284
|
+
n.host host
|
285
|
+
}
|
286
|
+
noip[:offline].each {|offline|
|
287
|
+
n.offline offline
|
288
|
+
}
|
289
|
+
}
|
223
290
|
else
|
224
291
|
die "You can't use a configure file with custom services"
|
225
292
|
end
|
data/lib/dyndyndong/services.rb
CHANGED
@@ -17,8 +17,6 @@
|
|
17
17
|
# along with dyndyndong. If not, see <http://www.gnu.org/licenses/>.
|
18
18
|
#++
|
19
19
|
|
20
|
-
$DEBUG = true
|
21
|
-
|
22
20
|
module DynDynDong
|
23
21
|
|
24
22
|
class Service
|
@@ -91,6 +89,6 @@ end
|
|
91
89
|
|
92
90
|
end
|
93
91
|
|
94
|
-
%w{afraid dyndns zoneedit}.each {|s|
|
92
|
+
%w{generic afraid dyndns zoneedit no-ip}.each {|s|
|
95
93
|
require "dyndyndong/services/#{s}"
|
96
94
|
}
|
@@ -17,14 +17,10 @@
|
|
17
17
|
# along with dyndyndong. If not, see <http://www.gnu.org/licenses/>.
|
18
18
|
#++
|
19
19
|
|
20
|
-
require 'net/http'
|
21
|
-
require 'resolv'
|
22
|
-
|
23
20
|
module DynDynDong
|
24
21
|
|
25
|
-
class DynDNS <
|
26
|
-
|
27
|
-
{
|
22
|
+
class DynDNS < Generic
|
23
|
+
set :MSGTABLE, {
|
28
24
|
'badauth' => 'The username and password pair do not match a real user.',
|
29
25
|
'!donator' => 'Option available only to credited users.',
|
30
26
|
'good' => 'The update was successful, and the hostname is now updated.',
|
@@ -37,84 +33,9 @@ class DynDNS < Service
|
|
37
33
|
'good 127.0.0.1' => 'Request was ignored because of agent that does not follow our specifications.',
|
38
34
|
'dnserr' => 'DNS error encountered.',
|
39
35
|
'911' => 'There is a problem or scheduled maintenance on our side.'
|
40
|
-
}[x]
|
41
|
-
end
|
42
|
-
|
43
|
-
def initialize(*args)
|
44
|
-
@user = nil
|
45
|
-
@pass = nil
|
46
|
-
@ip = getip
|
47
|
-
super(*args)
|
48
|
-
end
|
49
|
-
|
50
|
-
def username(u)
|
51
|
-
@user = u.to_s
|
52
|
-
end
|
53
|
-
|
54
|
-
def password(p)
|
55
|
-
@pass = p.to_s
|
56
|
-
end
|
57
|
-
|
58
|
-
alias username= username
|
59
|
-
alias password= password
|
60
|
-
|
61
|
-
def host(h)
|
62
|
-
begin
|
63
|
-
@hosts << [h.to_s, getip(h)]
|
64
|
-
rescue Exception => e
|
65
|
-
STDERR.puts "Ip detection error: #{e}, skipping..."
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
def offline(h)
|
70
|
-
begin
|
71
|
-
@hosts << [h.to_s, getip(h), true]
|
72
|
-
rescue Exception => e
|
73
|
-
STDERR.puts "Ip detection error: #{e}, skipping..."
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
def prefetch
|
78
|
-
if !(@user and @pass)
|
79
|
-
raise "username or password ungiven"
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
def alias_host(h, ip, offline = false)
|
84
|
-
return "Nothing to update." if ip == @ip
|
85
|
-
|
86
|
-
Net::HTTP.start(update_host) {|http|
|
87
|
-
req = Net::HTTP::Get.new('/nic/update?hostname=%s&myip=%s&offline=%s' % [
|
88
|
-
URI.escape(h), @ip, offline?(offline)])
|
89
|
-
req.basic_auth @user, @pass
|
90
|
-
x = http.request(req).body.gsub(/#{Regexp.escape(@ip)}/, '').strip
|
91
|
-
self::MSGTABLE(x)
|
92
36
|
}
|
93
|
-
|
94
|
-
|
95
|
-
private
|
96
|
-
def update_host
|
97
|
-
'members.dyndns.org'
|
98
|
-
end
|
99
|
-
|
100
|
-
def offline?(offline)
|
101
|
-
offline ? 'YES' : 'NOCHG'
|
102
|
-
end
|
103
|
-
|
104
|
-
def getip(h = nil)
|
105
|
-
if h
|
106
|
-
hosts = ""
|
107
|
-
Resolv.new.each_address(h){|ho| hosts = ho }
|
108
|
-
return hosts
|
109
|
-
end
|
110
|
-
str = Net::HTTP.get(URI.parse('http://checkip.dyndns.org/')).
|
111
|
-
match(/<body>(.+?)<\/body>/)[1] rescue ""
|
112
|
-
if str =~ /^Current IP Address: \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/
|
113
|
-
return str.gsub(/^Current IP Address: /, '')
|
114
|
-
else
|
115
|
-
raise "Couldn't retrieve ip."
|
116
|
-
end
|
117
|
-
end
|
37
|
+
set :OFFLINE, 'YES', 'NOCHG'
|
38
|
+
set :UPDATE_HOST, 'members.dyndns.org'
|
118
39
|
end
|
119
40
|
|
120
41
|
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
#--
|
2
|
+
# Copyleft shura. [shura1991@gmail.com]
|
3
|
+
#
|
4
|
+
# This file is part of DynDynDong.
|
5
|
+
#
|
6
|
+
# DynDynDong is free software: you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU Affero General Public License as published
|
8
|
+
# by the Free Software Foundation, either version 3 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# DynDynDong is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU Affero General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU Affero General Public License
|
17
|
+
# along with dyndyndong. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
#++
|
19
|
+
|
20
|
+
require 'net/http'
|
21
|
+
require 'resolv'
|
22
|
+
|
23
|
+
module DynDynDong
|
24
|
+
|
25
|
+
class Generic < Service
|
26
|
+
def initialize(*args)
|
27
|
+
@user = nil
|
28
|
+
@pass = nil
|
29
|
+
@ip = getip
|
30
|
+
super(*args)
|
31
|
+
end
|
32
|
+
|
33
|
+
def username(u)
|
34
|
+
@user = u.to_s
|
35
|
+
end
|
36
|
+
|
37
|
+
def password(p)
|
38
|
+
@pass = p.to_s
|
39
|
+
end
|
40
|
+
|
41
|
+
alias username= username
|
42
|
+
alias password= password
|
43
|
+
|
44
|
+
def host(h)
|
45
|
+
@hosts << [h.to_s]
|
46
|
+
end
|
47
|
+
|
48
|
+
def offline(h)
|
49
|
+
@hosts << [h.to_s, true]
|
50
|
+
end
|
51
|
+
|
52
|
+
def prefetch
|
53
|
+
raise "username or password ungiven" if !(@user and @pass)
|
54
|
+
@ip = getip
|
55
|
+
end
|
56
|
+
|
57
|
+
def alias_host(h, offline = false)
|
58
|
+
Net::HTTP.start(update_host) {|http|
|
59
|
+
req = Net::HTTP::Get.new('/nic/update?hostname=%s&myip=%s&offline=%s' % [
|
60
|
+
URI.escape(h), getip(h), offline?(offline)])
|
61
|
+
req.basic_auth @user, @pass
|
62
|
+
x = http.request(req).body.gsub(/#{Regexp.escape(@ip)}/, '').strip
|
63
|
+
MSGTABLE(x)
|
64
|
+
}
|
65
|
+
end
|
66
|
+
|
67
|
+
def self.set(*args)
|
68
|
+
sym = args.shift.to_s.downcase
|
69
|
+
case sym
|
70
|
+
when 'msgtable'
|
71
|
+
raise ArgumentError, "wrong number of arguments (#{args.size} for 1)" if args.size != 1
|
72
|
+
raise ArgumentError, "wrong type" if !args.first.is_a?(Hash)
|
73
|
+
self.class_eval %Q{
|
74
|
+
def MSGTABLE(x)
|
75
|
+
#{args.first.inspect}[x]
|
76
|
+
end
|
77
|
+
}
|
78
|
+
when 'update_host'
|
79
|
+
raise ArgumentError, "wrong number of arguments (#{args.size} for 1)" if args.size != 1
|
80
|
+
raise ArgumentError, "wrong type" if !args.first.is_a?(String)
|
81
|
+
self.class_eval %Q{
|
82
|
+
def update_host
|
83
|
+
#{args.first.inspect}
|
84
|
+
end
|
85
|
+
}
|
86
|
+
when 'offline'
|
87
|
+
raise ArgumentError, "wrong number of arguments (#{args.size} for 2)" if args.size != 2
|
88
|
+
raise ArgumentError, "wrong type" if !args[0].is_a?(String) or !args[1].is_a?(String)
|
89
|
+
self.class_eval %Q{
|
90
|
+
def offlines(what)
|
91
|
+
{
|
92
|
+
'YES' => #{args[0].inspect},
|
93
|
+
'NO' => #{args[1].inspect}
|
94
|
+
}[what]
|
95
|
+
end
|
96
|
+
}
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
private
|
101
|
+
|
102
|
+
def offlines(what)
|
103
|
+
{
|
104
|
+
'YES' => 'YES',
|
105
|
+
'NO' => 'NO'
|
106
|
+
}[what]
|
107
|
+
end
|
108
|
+
|
109
|
+
def offline?(offline)
|
110
|
+
offline ? offlines('YES') : offlines('NO')
|
111
|
+
end
|
112
|
+
|
113
|
+
def getip(h = nil)
|
114
|
+
if h
|
115
|
+
hosts = ""
|
116
|
+
Resolv.new.each_address(h) {|ho|
|
117
|
+
hosts = ho
|
118
|
+
}
|
119
|
+
return hosts
|
120
|
+
end
|
121
|
+
|
122
|
+
str = Net::HTTP.get(URI.parse('http://checkip.dyndns.org/')).
|
123
|
+
match(/<body>(.+?)<\/body>/)[1] rescue ""
|
124
|
+
if str =~ /^Current IP Address: \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/
|
125
|
+
return str.gsub(/^Current IP Address: /, '')
|
126
|
+
else
|
127
|
+
raise "Couldn't retrieve ip."
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
@@ -20,8 +20,7 @@
|
|
20
20
|
module DynDynDong
|
21
21
|
|
22
22
|
class NoIp < DynDNS
|
23
|
-
|
24
|
-
{
|
23
|
+
set :MSGTABLE, {
|
25
24
|
'good' => 'DNS hostname update successful.',
|
26
25
|
'nochg' => 'IP address is current, no update performed.',
|
27
26
|
'nohost' => 'Hostname supplied does not exist under specified account.',
|
@@ -31,17 +30,7 @@ class NoIp < DynDNS
|
|
31
30
|
'abuse' => 'Username is blocked due to abuse.',
|
32
31
|
'911' => 'A fatal error on our side such as a database outage.'
|
33
32
|
}
|
34
|
-
|
35
|
-
|
36
|
-
private
|
37
|
-
|
38
|
-
def update_host
|
39
|
-
'dynupdate.no-ip.com'
|
40
|
-
end
|
41
|
-
|
42
|
-
def offline?(offline)
|
43
|
-
super(offline).gsub(/CHG$/, '')
|
44
|
-
end
|
33
|
+
set :UPDATE_HOST, 'dynupdate.no-ip.com'
|
45
34
|
end
|
46
35
|
|
47
36
|
end
|
data/lib/dyndyndong/version.rb
CHANGED
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 0.0.
|
8
|
+
- 3
|
9
|
+
version: 0.0.3
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- shura
|
@@ -44,6 +44,7 @@ files:
|
|
44
44
|
- lib/dyndyndong/services.rb
|
45
45
|
- lib/dyndyndong/services/zoneedit.rb
|
46
46
|
- lib/dyndyndong/services/dyndns.rb
|
47
|
+
- lib/dyndyndong/services/generic.rb
|
47
48
|
- lib/dyndyndong/services/afraid.rb
|
48
49
|
- lib/dyndyndong/services/no-ip.rb
|
49
50
|
- lib/dyndyndong/daemon.rb
|