resolv 0.6.3 → 0.7.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b38c0a6bfbc3572750fa6aabfc908f518021868ae4fd523024e9a606a638ddd3
4
- data.tar.gz: 915329aaefb0c6deee41e8e61ecdf261d92a13978ce52587102d81439ba32acc
3
+ metadata.gz: c4c4e60f6c23abc6f116dfbea5e531d20f99eb85025e4682d3d85f580e17d09d
4
+ data.tar.gz: e609b5a2a67f67b5d7c616a2a3340d5ab3af305a29f66ab800785d62466ab883
5
5
  SHA512:
6
- metadata.gz: 84c70f3d4dd7837793d637007603f3b9c94963cd5ffdf01aa63fb8512750b2930158a1bbc9e3875e62895ad385eb9afdaa3790b253f610bef1bfed7e14dc29f0
7
- data.tar.gz: 7fc14713cf5fb4e92278da88e5c8c892ac7d6bcb5fd9ea69bab07346ca543eb1aa5b627fa08fe547975ad9584a444f121a1fb00c13e79fcb3ad5712b9f23b8a9
6
+ metadata.gz: 3eab1f21df971bd56cd9e23429fdef5da84a502c6d441dcf4cb3ff06fbf2c5222c7cd72b6d17a466d46b956bdeeeecfde0bc0254d78c37d73d1fd1c915bc0912
7
+ data.tar.gz: e81e097c7fc424ba72f2f84a07d933cb7bfb001f019ba2babb440c2a94e5aed2f38df688934cd0a35a5ed583ae73969b56ea7e6a92f1e8cdf4875a210d331003
data/.document ADDED
@@ -0,0 +1,4 @@
1
+ BSDL
2
+ COPYING
3
+ README.md
4
+ lib/
@@ -1,5 +1,6 @@
1
1
  require 'mkmf'
2
2
  if RUBY_ENGINE == "ruby" and have_library('iphlpapi', 'GetNetworkParams', ['windows.h', 'iphlpapi.h'])
3
+ have_library('advapi32', 'RegGetValueW', ['windows.h'])
3
4
  create_makefile('win32/resolv')
4
5
  else
5
6
  File.write('Makefile', "all clean install:\n\t@echo Done: $(@)\n")
@@ -4,8 +4,23 @@
4
4
 
5
5
  =end
6
6
 
7
+ require 'win32/resolv.so'
8
+
7
9
  module Win32
8
10
  module Resolv
11
+ # Error at Win32 API
12
+ class Error < StandardError
13
+ # +code+ Win32 Error code
14
+ # +message+ Formatted message for +code+
15
+ def initialize(code, message)
16
+ super(message)
17
+ @code = code
18
+ end
19
+
20
+ # Win32 error code
21
+ attr_reader :code
22
+ end
23
+
9
24
  def self.get_hosts_path
10
25
  path = get_hosts_dir
11
26
  path = File.expand_path('hosts', path)
@@ -29,121 +44,62 @@ module Win32
29
44
  end
30
45
  [ search, nameserver ]
31
46
  end
32
- end
33
- end
34
-
35
- begin
36
- require 'win32/resolv.so'
37
- rescue LoadError
38
- end
39
-
40
- module Win32
41
- #====================================================================
42
- # Windows NT
43
- #====================================================================
44
- module Resolv
45
- begin
46
- require 'win32/registry'
47
- module SZ
48
- refine Registry do
49
- # ad hoc workaround for broken registry
50
- def read_s(key)
51
- type, str = read(key)
52
- unless type == Registry::REG_SZ
53
- warn "Broken registry, #{name}\\#{key} was #{Registry.type2name(type)}, ignored"
54
- return String.new
55
- end
56
- str
57
- end
58
- end
59
- end
60
- using SZ
61
- rescue LoadError, Gem::LoadError
62
- require "open3"
63
- end
64
-
65
- TCPIP_NT = 'SYSTEM\CurrentControlSet\Services\Tcpip\Parameters'
66
47
 
67
48
  class << self
68
49
  private
69
50
  def get_hosts_dir
70
- get_item_property(TCPIP_NT, 'DataBasePath', expand: true)
51
+ tcpip_params do |params|
52
+ params.value('DataBasePath')
53
+ end
71
54
  end
72
55
 
73
56
  def get_info
74
57
  search = nil
75
58
  nameserver = get_dns_server_list
76
59
 
77
- slist = get_item_property(TCPIP_NT, 'SearchList')
78
- search = slist.split(/,\s*/) unless slist.empty?
60
+ tcpip_params do |params|
61
+ slist = params.value('SearchList')
62
+ search = slist.split(/,\s*/) if slist and !slist.empty?
79
63
 
80
- if add_search = search.nil?
81
- search = []
82
- nvdom = get_item_property(TCPIP_NT, 'NV Domain')
64
+ if add_search = search.nil?
65
+ search = []
66
+ domain = params.value('Domain')
83
67
 
84
- unless nvdom.empty?
85
- search = [ nvdom ]
86
- udmnd = get_item_property(TCPIP_NT, 'UseDomainNameDevolution', dword: true)
87
- if udmnd != 0
88
- if /^\w+\./ =~ nvdom
89
- devo = $'
68
+ if domain and !domain.empty?
69
+ search = [ domain ]
70
+ udmnd = params.value('UseDomainNameDevolution')
71
+ if udmnd&.nonzero?
72
+ if /^\w+\./ =~ domain
73
+ devo = $'
74
+ end
90
75
  end
91
76
  end
92
77
  end
93
- end
94
78
 
95
- ifs = if defined?(Win32::Registry)
96
- Registry::HKEY_LOCAL_MACHINE.open(TCPIP_NT + '\Interfaces') do |reg|
97
- reg.keys
98
- rescue Registry::Error
99
- []
100
- end
101
- else
102
- cmd = "Get-ChildItem 'HKLM:\\#{TCPIP_NT}\\Interfaces' | ForEach-Object { $_.PSChildName }"
103
- output, _ = Open3.capture2('powershell', '-Command', cmd)
104
- output.split(/\n+/)
79
+ params.open('Interfaces') do |reg|
80
+ reg.each_key do |iface|
81
+ next unless ns = %w[NameServer DhcpNameServer].find do |key|
82
+ ns = iface.value(key)
83
+ break ns.split(/[,\s]\s*/) if ns and !ns.empty?
105
84
  end
106
85
 
107
- ifs.each do |iface|
108
- next unless ns = %w[NameServer DhcpNameServer].find do |key|
109
- ns = get_item_property(TCPIP_NT + '\Interfaces' + "\\#{iface}", key)
110
- break ns.split(/[,\s]\s*/) unless ns.empty?
111
- end
112
-
113
- next if (nameserver & ns).empty?
86
+ next if (nameserver & ns).empty?
114
87
 
115
- if add_search
116
- [ 'Domain', 'DhcpDomain' ].each do |key|
117
- dom = get_item_property(TCPIP_NT + '\Interfaces' + "\\#{iface}", key)
118
- unless dom.empty?
119
- search.concat(dom.split(/,\s*/))
120
- break
88
+ if add_search
89
+ [ 'Domain', 'DhcpDomain' ].each do |key|
90
+ dom = iface.value(key)
91
+ if dom and !dom.empty?
92
+ search.concat(dom.split(/,\s*/))
93
+ break
94
+ end
95
+ end
121
96
  end
122
97
  end
123
98
  end
124
- end
125
- search << devo if add_search and devo
126
- [ search.uniq, nameserver.uniq ]
127
- end
128
99
 
129
- def get_item_property(path, name, expand: false, dword: false)
130
- if defined?(Win32::Registry)
131
- begin
132
- Registry::HKEY_LOCAL_MACHINE.open(path) do |reg|
133
- if dword
134
- reg.read_i(name)
135
- else
136
- expand ? reg.read_s_expand(name) : reg.read_s(name)
137
- end
138
- end
139
- rescue Registry::Error
140
- dword ? 0 : ""
141
- end
142
- else
143
- cmd = "Get-ItemProperty -Path 'HKLM:\\#{path}' -Name '#{name}' -ErrorAction SilentlyContinue | Select-Object -ExpandProperty '#{name}'"
144
- output, _ = Open3.capture2('powershell', '-Command', cmd)
145
- dword ? output.strip.to_i : output.strip
100
+ search << devo if add_search and devo
146
101
  end
102
+ [ search.uniq, nameserver.uniq ]
147
103
  end
148
104
  end
149
105
  end
@@ -1,24 +1,56 @@
1
1
  #include <ruby.h>
2
2
  #include <ruby/encoding.h>
3
3
  #include <windows.h>
4
+ #include <windns.h>
4
5
  #ifndef NTDDI_VERSION
5
6
  #define NTDDI_VERSION 0x06000000
6
7
  #endif
7
8
  #include <iphlpapi.h>
8
9
 
10
+ #ifndef numberof
11
+ #define numberof(array) ((int)(sizeof(array) / sizeof((array)[0])))
12
+ #endif
13
+
9
14
  static VALUE
10
15
  w32error_make_error(DWORD e)
11
16
  {
12
- VALUE code = ULONG2NUM(e);
13
- return rb_class_new_instance(1, &code, rb_path2class("Win32::Resolv::Error"));
17
+ char buffer[512], *p;
18
+ DWORD source = 0;
19
+ VALUE args[2];
20
+ if (!FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
21
+ FORMAT_MESSAGE_IGNORE_INSERTS, &source, e,
22
+ MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
23
+ buffer, sizeof(buffer), NULL)) {
24
+ snprintf(buffer, sizeof(buffer), "Unknown Error %lu", (unsigned long)e);
25
+ }
26
+ p = buffer;
27
+ while ((p = strpbrk(p, "\r\n")) != NULL) {
28
+ memmove(p, p + 1, strlen(p));
29
+ if (!p[1]) {
30
+ p[0] = '\0';
31
+ break;
32
+ }
33
+ }
34
+ args[0] = ULONG2NUM(e);
35
+ args[1] = rb_str_new_cstr(buffer);
36
+ return rb_class_new_instance(2, args, rb_path2class("Win32::Resolv::Error"));
14
37
  }
15
38
 
16
- NORETURN(static void w32error_raise(DWORD e));
17
-
18
39
  static void
19
- w32error_raise(DWORD e)
40
+ w32error_check(DWORD e)
41
+ {
42
+ if (e != NO_ERROR) {
43
+ rb_exc_raise(w32error_make_error(e));
44
+ }
45
+ }
46
+
47
+ static VALUE
48
+ wchar_to_utf8(const WCHAR *w, int n)
20
49
  {
21
- rb_exc_raise(w32error_make_error(e));
50
+ int clen = WideCharToMultiByte(CP_UTF8, 0, w, n, NULL, 0, NULL, NULL);
51
+ VALUE str = rb_enc_str_new(NULL, clen, rb_utf8_encoding());
52
+ WideCharToMultiByte(CP_UTF8, 0, w, n, RSTRING_PTR(str), clen, NULL, NULL);
53
+ return str;
22
54
  }
23
55
 
24
56
  static VALUE
@@ -30,9 +62,7 @@ get_dns_server_list(VALUE self)
30
62
  VALUE buf, nameservers = Qnil;
31
63
 
32
64
  ret = GetNetworkParams(NULL, &buflen);
33
- if (ret != NO_ERROR && ret != ERROR_BUFFER_OVERFLOW) {
34
- w32error_raise(ret);
35
- }
65
+ if (ret != ERROR_BUFFER_OVERFLOW) w32error_check(ret);
36
66
  fixedinfo = ALLOCV(buf, buflen);
37
67
  ret = GetNetworkParams(fixedinfo, &buflen);
38
68
  if (ret == NO_ERROR) {
@@ -46,18 +76,181 @@ get_dns_server_list(VALUE self)
46
76
  } while ((ipaddr = ipaddr->Next) != NULL);
47
77
  }
48
78
  ALLOCV_END(buf);
49
- if (ret != NO_ERROR) w32error_raise(ret);
79
+ w32error_check(ret);
50
80
 
51
81
  return nameservers;
52
82
  }
53
83
 
84
+
85
+ static const WCHAR TCPIP_Params[] = L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters";
86
+
87
+ static void
88
+ hkey_finalize(void *p)
89
+ {
90
+ RegCloseKey((HKEY)p);
91
+ }
92
+
93
+ static const rb_data_type_t hkey_type = {
94
+ "RegKey",
95
+ {0, hkey_finalize},
96
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY,
97
+ };
98
+
99
+ static VALUE
100
+ hkey_close(VALUE self)
101
+ {
102
+ RegCloseKey((HKEY)DATA_PTR(self));
103
+ DATA_PTR(self) = 0;
104
+ return self;
105
+ }
106
+
107
+ static VALUE reg_key_class;
108
+
109
+ static VALUE
110
+ reg_open_key(VALUE klass, HKEY hkey, const WCHAR *wname)
111
+ {
112
+ VALUE k = TypedData_Wrap_Struct(klass, &hkey_type, NULL);
113
+ DWORD e = RegOpenKeyExW(hkey, wname, 0, KEY_READ, (HKEY *)&DATA_PTR(k));
114
+ if (e == ERROR_FILE_NOT_FOUND) return Qnil;
115
+ w32error_check(e);
116
+ return rb_ensure(rb_yield, k, hkey_close, k);
117
+ }
118
+
119
+ static VALUE
120
+ tcpip_params_open(VALUE klass)
121
+ {
122
+ return reg_open_key(reg_key_class, HKEY_LOCAL_MACHINE, TCPIP_Params);
123
+ }
124
+
125
+ static int
126
+ to_wname(VALUE *name, WCHAR *wname, int wlen)
127
+ {
128
+ const char *n = StringValueCStr(*name);
129
+ int nlen = RSTRING_LEN(*name);
130
+ int len = MultiByteToWideChar(CP_UTF8, 0, n, nlen, wname, wlen - 1);
131
+ if (len == 0) w32error_check(GetLastError());
132
+ if (len >= wlen) rb_raise(rb_eArgError, "too long name");
133
+ wname[len] = L'\0';
134
+ return len;
135
+ }
136
+
137
+ static VALUE
138
+ reg_open(VALUE self, VALUE name)
139
+ {
140
+ HKEY hkey = DATA_PTR(self);
141
+ WCHAR wname[256];
142
+ to_wname(&name, wname, numberof(wname));
143
+ return reg_open_key(CLASS_OF(self), hkey, wname);
144
+ }
145
+
146
+
147
+ static VALUE
148
+ reg_each_key(VALUE self)
149
+ {
150
+ WCHAR wname[256];
151
+ HKEY hkey = DATA_PTR(self);
152
+ VALUE k = TypedData_Wrap_Struct(CLASS_OF(self), &hkey_type, NULL);
153
+ DWORD i, e, n;
154
+ for (i = 0; n = numberof(wname), (e = RegEnumKeyExW(hkey, i, wname, &n, NULL, NULL, NULL, NULL)) == ERROR_SUCCESS; i++) {
155
+ e = RegOpenKeyExW(hkey, wname, 0, KEY_READ, (HKEY *)&DATA_PTR(k));
156
+ w32error_check(e);
157
+ rb_ensure(rb_yield, k, hkey_close, k);
158
+ }
159
+ if (e != ERROR_NO_MORE_ITEMS) w32error_check(e);
160
+ return self;
161
+ }
162
+
163
+ static inline DWORD
164
+ swap_dw(DWORD x)
165
+ {
166
+ #if defined(_MSC_VER)
167
+ return _byteswap_ulong(x);
168
+ #else
169
+ return __builtin_bswap32(x);
170
+ #endif
171
+ }
172
+
173
+ static VALUE
174
+ reg_value(VALUE self, VALUE name)
175
+ {
176
+ HKEY hkey = DATA_PTR(self);
177
+ DWORD type = 0, size = 0, e;
178
+ VALUE result, value_buffer;
179
+ void *buffer;
180
+ WCHAR wname[256];
181
+ to_wname(&name, wname, numberof(wname));
182
+ e = RegGetValueW(hkey, NULL, wname, RRF_RT_ANY, &type, NULL, &size);
183
+ if (e == ERROR_FILE_NOT_FOUND) return Qnil;
184
+ w32error_check(e);
185
+ # define get_value_2nd(data, dsize) do { \
186
+ DWORD type2 = type; \
187
+ w32error_check(RegGetValueW(hkey, NULL, wname, RRF_RT_ANY, &type2, data, dsize)); \
188
+ if (type != type2) { \
189
+ rb_raise(rb_eRuntimeError, "registry value type changed %lu -> %lu", \
190
+ (unsigned long)type, (unsigned long)type2); \
191
+ } \
192
+ } while (0)
193
+
194
+ switch (type) {
195
+ case REG_DWORD: case REG_DWORD_BIG_ENDIAN:
196
+ {
197
+ DWORD d;
198
+ if (size != sizeof(d)) rb_raise(rb_eRuntimeError, "invalid size returned: %lu", (unsigned long)size);
199
+ w32error_check(RegGetValueW(hkey, NULL, wname, RRF_RT_REG_DWORD, &type, &d, &size));
200
+ if (type == REG_DWORD_BIG_ENDIAN) d = swap_dw(d);
201
+ return ULONG2NUM(d);
202
+ }
203
+ case REG_QWORD:
204
+ {
205
+ QWORD q;
206
+ if (size != sizeof(q)) rb_raise(rb_eRuntimeError, "invalid size returned: %lu", (unsigned long)size);
207
+ w32error_check(RegGetValueW(hkey, NULL, wname, RRF_RT_REG_QWORD, &type, &q, &size));
208
+ return ULL2NUM(q);
209
+ }
210
+ case REG_SZ: case REG_MULTI_SZ: case REG_EXPAND_SZ:
211
+ if (size % sizeof(WCHAR)) rb_raise(rb_eRuntimeError, "invalid size returned: %lu", (unsigned long)size);
212
+ buffer = ALLOCV_N(char, value_buffer, size);
213
+ get_value_2nd(buffer, &size);
214
+ if (type == REG_MULTI_SZ) {
215
+ const WCHAR *w = (WCHAR *)buffer;
216
+ result = rb_ary_new();
217
+ size /= sizeof(WCHAR);
218
+ size -= 1;
219
+ for (size_t i = 0; i < size; ++i) {
220
+ int n = lstrlenW(w+i);
221
+ rb_ary_push(result, wchar_to_utf8(w+i, n));
222
+ i += n;
223
+ }
224
+ }
225
+ else {
226
+ result = wchar_to_utf8((WCHAR *)buffer, lstrlenW((WCHAR *)buffer));
227
+ }
228
+ ALLOCV_END(value_buffer);
229
+ break;
230
+ default:
231
+ result = rb_str_new(0, size);
232
+ get_value_2nd(RSTRING_PTR(result), &size);
233
+ rb_str_set_len(result, size);
234
+ break;
235
+ }
236
+ return result;
237
+ }
238
+
54
239
  void
55
240
  InitVM_resolv(void)
56
241
  {
57
242
  VALUE mWin32 = rb_define_module("Win32");
58
243
  VALUE resolv = rb_define_module_under(mWin32, "Resolv");
59
244
  VALUE singl = rb_singleton_class(resolv);
245
+ VALUE regkey = rb_define_class_under(resolv, "registry key", rb_cObject);
246
+
247
+ reg_key_class = regkey;
248
+ rb_undef_alloc_func(regkey);
60
249
  rb_define_private_method(singl, "get_dns_server_list", get_dns_server_list, 0);
250
+ rb_define_private_method(singl, "tcpip_params", tcpip_params_open, 0);
251
+ rb_define_method(regkey, "open", reg_open, 1);
252
+ rb_define_method(regkey, "each_key", reg_each_key, 0);
253
+ rb_define_method(regkey, "value", reg_value, 1);
61
254
  }
62
255
 
63
256
  void
data/lib/resolv.rb CHANGED
@@ -34,7 +34,8 @@ require 'rbconfig'
34
34
 
35
35
  class Resolv
36
36
 
37
- VERSION = "0.6.3"
37
+ # The version string
38
+ VERSION = "0.7.1"
38
39
 
39
40
  ##
40
41
  # Looks up the first IP address for +name+.
@@ -174,21 +175,19 @@ class Resolv
174
175
 
175
176
  class ResolvTimeout < Timeout::Error; end
176
177
 
177
- WINDOWS = /mswin|cygwin|mingw|bccwin/ =~ RUBY_PLATFORM || ::RbConfig::CONFIG['host_os'] =~ /mswin/
178
- private_constant :WINDOWS
179
-
180
178
  ##
181
179
  # Resolv::Hosts is a hostname resolver that uses the system hosts file.
182
180
 
183
181
  class Hosts
184
- if WINDOWS
182
+ if /mswin|cygwin|mingw|bccwin/ =~ RUBY_PLATFORM || ::RbConfig::CONFIG['host_os'] =~ /mswin/
185
183
  begin
186
184
  require 'win32/resolv' unless defined?(Win32::Resolv)
187
- DefaultFileName = Win32::Resolv.get_hosts_path || IO::NULL
185
+ hosts = Win32::Resolv.get_hosts_path || IO::NULL
188
186
  rescue LoadError
189
187
  end
190
188
  end
191
- DefaultFileName ||= '/etc/hosts'
189
+ # The default file name for host names
190
+ DefaultFileName = hosts || '/etc/hosts'
192
191
 
193
192
  ##
194
193
  # Creates a new Resolv::Hosts, using +filename+ for its data source.
@@ -488,13 +487,18 @@ class Resolv
488
487
  # * Resolv::DNS::Resource::IN::A
489
488
  # * Resolv::DNS::Resource::IN::AAAA
490
489
  # * Resolv::DNS::Resource::IN::ANY
490
+ # * Resolv::DNS::Resource::IN::CAA
491
491
  # * Resolv::DNS::Resource::IN::CNAME
492
492
  # * Resolv::DNS::Resource::IN::HINFO
493
+ # * Resolv::DNS::Resource::IN::HTTPS
494
+ # * Resolv::DNS::Resource::IN::LOC
493
495
  # * Resolv::DNS::Resource::IN::MINFO
494
496
  # * Resolv::DNS::Resource::IN::MX
495
497
  # * Resolv::DNS::Resource::IN::NS
496
498
  # * Resolv::DNS::Resource::IN::PTR
497
499
  # * Resolv::DNS::Resource::IN::SOA
500
+ # * Resolv::DNS::Resource::IN::SRV
501
+ # * Resolv::DNS::Resource::IN::SVCB
498
502
  # * Resolv::DNS::Resource::IN::TXT
499
503
  # * Resolv::DNS::Resource::IN::WKS
500
504
  #
@@ -526,6 +530,8 @@ class Resolv
526
530
  }
527
531
  end
528
532
 
533
+ # :stopdoc:
534
+
529
535
  def fetch_resource(name, typeclass)
530
536
  lazy_initialize
531
537
  truncated = {}
@@ -720,7 +726,8 @@ class Resolv
720
726
  begin
721
727
  reply, from = recv_reply(select_result[0])
722
728
  rescue Errno::ECONNREFUSED, # GNU/Linux, FreeBSD
723
- Errno::ECONNRESET # Windows
729
+ Errno::ECONNRESET, # Windows
730
+ EOFError
724
731
  # No name server running on the server?
725
732
  # Don't wait anymore.
726
733
  raise ResolvTimeout
@@ -929,8 +936,11 @@ class Resolv
929
936
  end
930
937
 
931
938
  def recv_reply(readable_socks)
932
- len = readable_socks[0].read(2).unpack('n')[0]
939
+ len_data = readable_socks[0].read(2)
940
+ raise EOFError if len_data.nil? || len_data.bytesize != 2
941
+ len = len_data.unpack('n')[0]
933
942
  reply = @socks[0].read(len)
943
+ raise EOFError if reply.nil? || reply.bytesize != len
934
944
  return reply, nil
935
945
  end
936
946
 
@@ -1022,8 +1032,7 @@ class Resolv
1022
1032
  def Config.default_config_hash(filename="/etc/resolv.conf")
1023
1033
  if File.exist? filename
1024
1034
  Config.parse_resolv_conf(filename)
1025
- elsif WINDOWS
1026
- require 'win32/resolv' unless defined?(Win32::Resolv)
1035
+ elsif defined?(Win32::Resolv)
1027
1036
  search, nameserver = Win32::Resolv.get_resolv_info
1028
1037
  config_hash = {}
1029
1038
  config_hash[:nameserver] = nameserver if nameserver
@@ -2927,15 +2936,21 @@ class Resolv
2927
2936
 
2928
2937
  class IPv4
2929
2938
 
2930
- ##
2931
- # Regular expression IPv4 addresses must match.
2932
-
2933
2939
  Regex256 = /0
2934
2940
  |1(?:[0-9][0-9]?)?
2935
2941
  |2(?:[0-4][0-9]?|5[0-5]?|[6-9])?
2936
- |[3-9][0-9]?/x
2942
+ |[3-9][0-9]?/x # :nodoc:
2943
+
2944
+ ##
2945
+ # Regular expression IPv4 addresses must match.
2937
2946
  Regex = /\A(#{Regex256})\.(#{Regex256})\.(#{Regex256})\.(#{Regex256})\z/
2938
2947
 
2948
+ ##
2949
+ # Creates a new IPv4 address from +arg+ which may be:
2950
+ #
2951
+ # IPv4:: returns +arg+.
2952
+ # String:: +arg+ must match the IPv4::Regex constant
2953
+
2939
2954
  def self.create(arg)
2940
2955
  case arg
2941
2956
  when IPv4
@@ -3244,13 +3259,15 @@ class Resolv
3244
3259
 
3245
3260
  end
3246
3261
 
3247
- module LOC
3262
+ module LOC # :nodoc:
3248
3263
 
3249
3264
  ##
3250
3265
  # A Resolv::LOC::Size
3251
3266
 
3252
3267
  class Size
3253
3268
 
3269
+ # Regular expression LOC size must match.
3270
+
3254
3271
  Regex = /^(\d+\.*\d*)[m]$/
3255
3272
 
3256
3273
  ##
@@ -3276,6 +3293,7 @@ class Resolv
3276
3293
  end
3277
3294
  end
3278
3295
 
3296
+ # Internal use; use self.create.
3279
3297
  def initialize(scalar)
3280
3298
  @scalar = scalar
3281
3299
  end
@@ -3313,6 +3331,8 @@ class Resolv
3313
3331
 
3314
3332
  class Coord
3315
3333
 
3334
+ # Regular expression LOC Coord must match.
3335
+
3316
3336
  Regex = /^(\d+)\s(\d+)\s(\d+\.\d+)\s([NESW])$/
3317
3337
 
3318
3338
  ##
@@ -3342,6 +3362,7 @@ class Resolv
3342
3362
  end
3343
3363
  end
3344
3364
 
3365
+ # Internal use; use self.create.
3345
3366
  def initialize(coordinates,orientation)
3346
3367
  unless coordinates.kind_of?(String)
3347
3368
  raise ArgumentError.new("Coord must be a 32bit unsigned integer in hex format: #{coordinates.inspect}")
@@ -3404,6 +3425,8 @@ class Resolv
3404
3425
 
3405
3426
  class Alt
3406
3427
 
3428
+ # Regular expression LOC Alt must match.
3429
+
3407
3430
  Regex = /^([+-]*\d+\.*\d*)[m]$/
3408
3431
 
3409
3432
  ##
@@ -3429,6 +3452,7 @@ class Resolv
3429
3452
  end
3430
3453
  end
3431
3454
 
3455
+ # Internal use; use self.create.
3432
3456
  def initialize(altitude)
3433
3457
  @altitude = altitude
3434
3458
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: resolv
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.3
4
+ version: 0.7.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tanaka Akira
@@ -17,25 +17,14 @@ extensions:
17
17
  - ext/win32/resolv/extconf.rb
18
18
  extra_rdoc_files: []
19
19
  files:
20
- - ".git-blame-ignore-revs"
21
- - ".github/dependabot.yml"
22
- - ".github/release.yml"
23
- - ".github/workflows/push_gem.yml"
24
- - ".github/workflows/sync-ruby.yml"
25
- - ".github/workflows/test.yml"
26
- - ".gitignore"
20
+ - ".document"
27
21
  - BSDL
28
22
  - COPYING
29
- - Gemfile
30
23
  - README.md
31
- - Rakefile
32
- - bin/console
33
- - bin/setup
34
24
  - ext/win32/resolv/extconf.rb
35
25
  - ext/win32/resolv/lib/resolv.rb
36
26
  - ext/win32/resolv/resolv.c
37
27
  - lib/resolv.rb
38
- - resolv.gemspec
39
28
  homepage: https://github.com/ruby/resolv
40
29
  licenses:
41
30
  - Ruby
@@ -1,7 +0,0 @@
1
- # This is a file used by GitHub to ignore the following commits on `git blame`.
2
- #
3
- # You can also do the same thing in your local repository with:
4
- # $ git config --local blame.ignoreRevsFile .git-blame-ignore-revs
5
-
6
- # Expand tabs
7
- 9ae210665a8524554e7c868d3ec67af54b0958bb
@@ -1,6 +0,0 @@
1
- version: 2
2
- updates:
3
- - package-ecosystem: 'github-actions'
4
- directory: '/'
5
- schedule:
6
- interval: 'weekly'
data/.github/release.yml DELETED
@@ -1,4 +0,0 @@
1
- changelog:
2
- exclude:
3
- labels:
4
- - dependencies # Added by Dependabot
@@ -1,46 +0,0 @@
1
- name: Publish gem to rubygems.org
2
-
3
- on:
4
- push:
5
- tags:
6
- - 'v*'
7
-
8
- permissions:
9
- contents: read
10
-
11
- jobs:
12
- push:
13
- if: github.repository == 'ruby/resolv'
14
- runs-on: ubuntu-latest
15
-
16
- environment:
17
- name: rubygems.org
18
- url: https://rubygems.org/gems/resolv
19
-
20
- permissions:
21
- contents: write
22
- id-token: write
23
-
24
- steps:
25
- - name: Harden Runner
26
- uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
27
- with:
28
- egress-policy: audit
29
-
30
- - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
31
-
32
- - name: Set up Ruby
33
- uses: ruby/setup-ruby@d5126b9b3579e429dd52e51e68624dda2e05be25 # v1.267.0
34
- with:
35
- bundler-cache: true
36
- ruby-version: ruby
37
-
38
- - name: Publish to RubyGems
39
- uses: rubygems/release-gem@1c162a739e8b4cb21a676e97b087e8268d8fc40b # v1.1.2
40
-
41
- - name: Create GitHub release
42
- run: |
43
- tag_name="$(git describe --tags --abbrev=0)"
44
- gh release create "${tag_name}" --verify-tag --generate-notes
45
- env:
46
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -1,33 +0,0 @@
1
- name: Sync ruby
2
- on:
3
- push:
4
- branches: [master]
5
- jobs:
6
- sync:
7
- name: Sync ruby
8
- runs-on: ubuntu-latest
9
- if: ${{ github.repository_owner == 'ruby' }}
10
- steps:
11
- - uses: actions/checkout@v5
12
-
13
- - name: Create GitHub App token
14
- id: app-token
15
- uses: actions/create-github-app-token@v2
16
- with:
17
- app-id: 2060836
18
- private-key: ${{ secrets.RUBY_SYNC_DEFAULT_GEMS_PRIVATE_KEY }}
19
- owner: ruby
20
- repositories: ruby
21
-
22
- - name: Sync to ruby/ruby
23
- uses: convictional/trigger-workflow-and-wait@v1.6.5
24
- with:
25
- owner: ruby
26
- repo: ruby
27
- workflow_file_name: sync_default_gems.yml
28
- github_token: ${{ steps.app-token.outputs.token }}
29
- ref: master
30
- client_payload: |
31
- {"gem":"${{ github.event.repository.name }}","before":"${{ github.event.before }}","after":"${{ github.event.after }}"}
32
- propagate_failure: true
33
- wait_interval: 10
@@ -1,52 +0,0 @@
1
- name: test
2
-
3
- on: [push, pull_request]
4
-
5
- jobs:
6
- ruby-versions:
7
- uses: ruby/actions/.github/workflows/ruby_versions.yml@master
8
- with:
9
- engine: cruby-jruby
10
- min_version: 2.5
11
-
12
- build:
13
- needs: ruby-versions
14
- name: build (${{ matrix.ruby }} / ${{ matrix.os }})
15
- strategy:
16
- matrix:
17
- ruby: ${{ fromJson(needs.ruby-versions.outputs.versions) }}
18
- os: [ ubuntu-latest, macos-latest, windows-latest ]
19
- include:
20
- - ruby: mswin
21
- os: windows-latest
22
- exclude:
23
- - ruby: 2.5
24
- os: macos-latest
25
- runs-on: ${{ matrix.os }}
26
- steps:
27
- - uses: actions/checkout@v5
28
- - name: Set up Ruby
29
- uses: ruby/setup-ruby@v1
30
- with:
31
- ruby-version: ${{ matrix.ruby }}
32
- bundler-cache: true
33
- - name: Run test
34
- run: bundle exec rake test
35
- timeout-minutes: 3
36
- continue-on-error: ${{ startsWith(matrix.ruby, 'jruby') }}
37
- - name: Build package
38
- id: build
39
- shell: bash
40
- run: |
41
- if ruby -e 'exit RUBY_VERSION>="3.0."'; then
42
- bundle exec rake build
43
- set pkg/*.gem
44
- echo pkg=$1 >> $GITHUB_OUTPUT
45
- fi
46
- - name: Install gem
47
- run: |
48
- gem install ${{ steps.build.outputs.pkg }}
49
- ruby -rresolv -e 'puts $LOADED_FEATURES.grep(/resolv/)'
50
- ruby -rresolv -e 'puts Resolv::VERSION'
51
- if: ${{ steps.build.outputs.pkg }}
52
- continue-on-error: ${{ startsWith(matrix.ruby, 'jruby') }}
data/.gitignore DELETED
@@ -1,11 +0,0 @@
1
- /.build/
2
- /.bundle/
3
- /.yardoc
4
- /_yardoc/
5
- /coverage/
6
- /doc/
7
- /pkg/
8
- /spec/reports/
9
- /tmp/
10
-
11
- Gemfile.lock
data/Gemfile DELETED
@@ -1,8 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- gemspec
4
-
5
- gem "rake"
6
- gem "test-unit"
7
- gem "test-unit-ruby-core"
8
- gem "ruby-core-tasks", github: "ruby/ruby-core-tasks"
data/Rakefile DELETED
@@ -1,18 +0,0 @@
1
- require "bundler/gem_tasks"
2
- require "rake/testtask"
3
-
4
- if RUBY_ENGINE == "ruby"
5
- require "ruby-core/extensiontask"
6
- helper = Bundler::GemHelper.instance
7
- extask = RubyCore::ExtensionTask.new(helper.gemspec)
8
- task :test => :compile
9
- end
10
-
11
- Rake::TestTask.new(:test) do |t|
12
- t.libs.unshift(*extask.libs) if extask
13
- t.libs << "test/lib"
14
- t.ruby_opts << "-rhelper"
15
- t.test_files = FileList["test/**/test_*.rb"]
16
- end
17
-
18
- task :default => :test
data/bin/console DELETED
@@ -1,14 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require "bundler/setup"
4
- require "resolv"
5
-
6
- # You can add fixtures and/or initialization code here to make experimenting
7
- # with your gem easier. You can also use a different console, if you like.
8
-
9
- # (If you use this, don't forget to add pry to your Gemfile!)
10
- # require "pry"
11
- # Pry.start
12
-
13
- require "irb"
14
- IRB.start(__FILE__)
data/bin/setup DELETED
@@ -1,8 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
- set -vx
5
-
6
- bundle install
7
-
8
- # Do any other automated setup that you need to do here
data/resolv.gemspec DELETED
@@ -1,30 +0,0 @@
1
- name = File.basename(__FILE__, ".gemspec")
2
- version = ["lib", Array.new(name.count("-")+1).join("/")].find do |dir|
3
- break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
4
- /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
5
- end rescue nil
6
- end
7
-
8
- Gem::Specification.new do |spec|
9
- spec.name = name
10
- spec.version = version
11
- spec.authors = ["Tanaka Akira"]
12
- spec.email = ["akr@fsij.org"]
13
-
14
- spec.summary = %q{Thread-aware DNS resolver library in Ruby.}
15
- spec.description = %q{Thread-aware DNS resolver library in Ruby.}
16
- spec.homepage = "https://github.com/ruby/resolv"
17
- spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
18
- spec.licenses = ["Ruby", "BSD-2-Clause"]
19
- spec.extensions << "ext/win32/resolv/extconf.rb"
20
-
21
- spec.metadata["homepage_uri"] = spec.homepage
22
- spec.metadata["source_code_uri"] = spec.homepage
23
-
24
- spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
25
- `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
26
- end
27
- spec.bindir = "exe"
28
- spec.executables = []
29
- spec.require_paths = ["lib"]
30
- end