resolv 0.6.0 → 0.7.0
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 +4 -4
- data/.document +4 -0
- data/README.md +6 -4
- data/ext/win32/resolv/extconf.rb +2 -1
- data/ext/win32/resolv/lib/resolv.rb +42 -71
- data/ext/win32/resolv/resolv.c +203 -8
- data/lib/resolv.rb +73 -29
- metadata +4 -16
- data/.git-blame-ignore-revs +0 -7
- data/.github/dependabot.yml +0 -6
- data/.github/workflows/push_gem.yml +0 -46
- data/.github/workflows/test.yml +0 -52
- data/.gitignore +0 -10
- data/Gemfile +0 -8
- data/Rakefile +0 -18
- data/bin/console +0 -14
- data/bin/setup +0 -8
- data/resolv.gemspec +0 -30
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2a32f99ca7eadc476467c7da9dbc5cfeb8152761da79306c91b21182141cbd44
|
|
4
|
+
data.tar.gz: 2605e997fbe45d690ea5cdb82f7128a02fcb03d6b4150f2c6eea44747edb852a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4529d93d71f7139c6eb0a29c7c3d69d0817ad092b9bbb8a6718b8588c0fc43aec45c84db4e3684fb7320548a238c5122198812474d0bac8292ca0891fa687c91
|
|
7
|
+
data.tar.gz: 9fcbff9a156782b6f5a8247262c237b3ba22c1843205a3ddc2d47b185e46fe959a2b62651b21c1573141748b35f8fe6063ab3c445f285d1990b35d1f129eaf44
|
data/.document
ADDED
data/README.md
CHANGED
|
@@ -14,15 +14,18 @@ gem 'resolv'
|
|
|
14
14
|
|
|
15
15
|
And then execute:
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
```bash
|
|
18
|
+
bundle install
|
|
19
|
+
```
|
|
18
20
|
|
|
19
21
|
Or install it yourself as:
|
|
20
22
|
|
|
21
|
-
|
|
23
|
+
```bash
|
|
24
|
+
gem install resolv
|
|
25
|
+
```
|
|
22
26
|
|
|
23
27
|
## Usage
|
|
24
28
|
|
|
25
|
-
|
|
26
29
|
```ruby
|
|
27
30
|
p Resolv.getaddress "www.ruby-lang.org"
|
|
28
31
|
p Resolv.getname "210.251.121.214"
|
|
@@ -44,4 +47,3 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
|
44
47
|
## Contributing
|
|
45
48
|
|
|
46
49
|
Bug reports and pull requests are welcome on GitHub at https://github.com/ruby/resolv.
|
|
47
|
-
|
data/ext/win32/resolv/extconf.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
require 'mkmf'
|
|
2
|
-
if RUBY_ENGINE == "ruby" and have_library('iphlpapi', 'GetNetworkParams')
|
|
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,12 +4,22 @@
|
|
|
4
4
|
|
|
5
5
|
=end
|
|
6
6
|
|
|
7
|
-
require 'win32/
|
|
7
|
+
require 'win32/resolv.so'
|
|
8
8
|
|
|
9
9
|
module Win32
|
|
10
10
|
module Resolv
|
|
11
|
-
|
|
12
|
-
Error
|
|
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
|
|
13
23
|
|
|
14
24
|
def self.get_hosts_path
|
|
15
25
|
path = get_hosts_dir
|
|
@@ -34,98 +44,59 @@ module Win32
|
|
|
34
44
|
end
|
|
35
45
|
[ search, nameserver ]
|
|
36
46
|
end
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
begin
|
|
41
|
-
require 'win32/resolv.so'
|
|
42
|
-
rescue LoadError
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
module Win32
|
|
46
|
-
#====================================================================
|
|
47
|
-
# Windows NT
|
|
48
|
-
#====================================================================
|
|
49
|
-
module Resolv
|
|
50
|
-
module SZ
|
|
51
|
-
refine Registry do
|
|
52
|
-
# ad hoc workaround for broken registry
|
|
53
|
-
def read_s(key)
|
|
54
|
-
type, str = read(key)
|
|
55
|
-
unless type == Registry::REG_SZ
|
|
56
|
-
warn "Broken registry, #{name}\\#{key} was #{Registry.type2name(type)}, ignored"
|
|
57
|
-
return String.new
|
|
58
|
-
end
|
|
59
|
-
str
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
using SZ
|
|
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
|
-
|
|
71
|
-
|
|
51
|
+
tcpip_params do |params|
|
|
52
|
+
params.value('DataBasePath')
|
|
72
53
|
end
|
|
73
54
|
end
|
|
74
55
|
|
|
75
56
|
def get_info
|
|
76
57
|
search = nil
|
|
77
58
|
nameserver = get_dns_server_list
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
rescue Registry::Error
|
|
83
|
-
end
|
|
59
|
+
|
|
60
|
+
tcpip_params do |params|
|
|
61
|
+
slist = params.value('SearchList')
|
|
62
|
+
search = slist.split(/,\s*/) if slist and !slist.empty?
|
|
84
63
|
|
|
85
64
|
if add_search = search.nil?
|
|
86
65
|
search = []
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
66
|
+
domain = params.value('Domain')
|
|
67
|
+
|
|
68
|
+
if domain and !domain.empty?
|
|
69
|
+
search = [ domain ]
|
|
70
|
+
udmnd = params.value('UseDomainNameDevolution')
|
|
71
|
+
if udmnd&.nonzero?
|
|
72
|
+
if /^\w+\./ =~ domain
|
|
73
|
+
devo = $'
|
|
95
74
|
end
|
|
96
75
|
end
|
|
97
|
-
rescue Registry::Error
|
|
98
76
|
end
|
|
99
77
|
end
|
|
100
78
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
break ns.split(/[,\s]\s*/) unless ns.empty?
|
|
110
|
-
end
|
|
111
|
-
end
|
|
112
|
-
next if (nameserver & ns).empty?
|
|
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?
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
next if (nameserver & ns).empty?
|
|
113
87
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
break
|
|
121
|
-
end
|
|
122
|
-
end
|
|
123
|
-
rescue Registry::Error
|
|
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
|
|
124
94
|
end
|
|
125
95
|
end
|
|
126
96
|
end
|
|
127
97
|
end
|
|
128
98
|
end
|
|
99
|
+
|
|
129
100
|
search << devo if add_search and devo
|
|
130
101
|
end
|
|
131
102
|
[ search.uniq, nameserver.uniq ]
|
data/ext/win32/resolv/resolv.c
CHANGED
|
@@ -1,22 +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
|
-
|
|
13
|
-
|
|
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
39
|
static void
|
|
17
|
-
|
|
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)
|
|
18
49
|
{
|
|
19
|
-
|
|
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;
|
|
20
54
|
}
|
|
21
55
|
|
|
22
56
|
static VALUE
|
|
@@ -28,9 +62,7 @@ get_dns_server_list(VALUE self)
|
|
|
28
62
|
VALUE buf, nameservers = Qnil;
|
|
29
63
|
|
|
30
64
|
ret = GetNetworkParams(NULL, &buflen);
|
|
31
|
-
if (ret !=
|
|
32
|
-
w32error_raise(ret);
|
|
33
|
-
}
|
|
65
|
+
if (ret != ERROR_BUFFER_OVERFLOW) w32error_check(ret);
|
|
34
66
|
fixedinfo = ALLOCV(buf, buflen);
|
|
35
67
|
ret = GetNetworkParams(fixedinfo, &buflen);
|
|
36
68
|
if (ret == NO_ERROR) {
|
|
@@ -44,18 +76,181 @@ get_dns_server_list(VALUE self)
|
|
|
44
76
|
} while ((ipaddr = ipaddr->Next) != NULL);
|
|
45
77
|
}
|
|
46
78
|
ALLOCV_END(buf);
|
|
47
|
-
|
|
79
|
+
w32error_check(ret);
|
|
48
80
|
|
|
49
81
|
return nameservers;
|
|
50
82
|
}
|
|
51
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
|
+
|
|
52
239
|
void
|
|
53
240
|
InitVM_resolv(void)
|
|
54
241
|
{
|
|
55
242
|
VALUE mWin32 = rb_define_module("Win32");
|
|
56
243
|
VALUE resolv = rb_define_module_under(mWin32, "Resolv");
|
|
57
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);
|
|
58
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);
|
|
59
254
|
}
|
|
60
255
|
|
|
61
256
|
void
|
data/lib/resolv.rb
CHANGED
|
@@ -4,6 +4,7 @@ require 'socket'
|
|
|
4
4
|
require 'timeout'
|
|
5
5
|
require 'io/wait'
|
|
6
6
|
require 'securerandom'
|
|
7
|
+
require 'rbconfig'
|
|
7
8
|
|
|
8
9
|
# Resolv is a thread-aware DNS resolver library written in Ruby. Resolv can
|
|
9
10
|
# handle multiple DNS requests concurrently without blocking the entire Ruby
|
|
@@ -33,7 +34,8 @@ require 'securerandom'
|
|
|
33
34
|
|
|
34
35
|
class Resolv
|
|
35
36
|
|
|
36
|
-
|
|
37
|
+
# The version string
|
|
38
|
+
VERSION = "0.7.0"
|
|
37
39
|
|
|
38
40
|
##
|
|
39
41
|
# Looks up the first IP address for +name+.
|
|
@@ -177,14 +179,15 @@ class Resolv
|
|
|
177
179
|
# Resolv::Hosts is a hostname resolver that uses the system hosts file.
|
|
178
180
|
|
|
179
181
|
class Hosts
|
|
180
|
-
if /mswin|mingw|
|
|
182
|
+
if /mswin|cygwin|mingw|bccwin/ =~ RUBY_PLATFORM || ::RbConfig::CONFIG['host_os'] =~ /mswin/
|
|
181
183
|
begin
|
|
182
|
-
require 'win32/resolv'
|
|
183
|
-
|
|
184
|
+
require 'win32/resolv' unless defined?(Win32::Resolv)
|
|
185
|
+
hosts = Win32::Resolv.get_hosts_path || IO::NULL
|
|
184
186
|
rescue LoadError
|
|
185
187
|
end
|
|
186
188
|
end
|
|
187
|
-
|
|
189
|
+
# The default file name for host names
|
|
190
|
+
DefaultFileName = hosts || '/etc/hosts'
|
|
188
191
|
|
|
189
192
|
##
|
|
190
193
|
# Creates a new Resolv::Hosts, using +filename+ for its data source.
|
|
@@ -522,6 +525,8 @@ class Resolv
|
|
|
522
525
|
}
|
|
523
526
|
end
|
|
524
527
|
|
|
528
|
+
# :stopdoc:
|
|
529
|
+
|
|
525
530
|
def fetch_resource(name, typeclass)
|
|
526
531
|
lazy_initialize
|
|
527
532
|
truncated = {}
|
|
@@ -659,8 +664,20 @@ class Resolv
|
|
|
659
664
|
}
|
|
660
665
|
end
|
|
661
666
|
|
|
662
|
-
|
|
663
|
-
|
|
667
|
+
case RUBY_PLATFORM
|
|
668
|
+
when *[
|
|
669
|
+
# https://www.rfc-editor.org/rfc/rfc6056.txt
|
|
670
|
+
# Appendix A. Survey of the Algorithms in Use by Some Popular Implementations
|
|
671
|
+
/freebsd/, /linux/, /netbsd/, /openbsd/, /solaris/,
|
|
672
|
+
/darwin/, # the same as FreeBSD
|
|
673
|
+
] then
|
|
674
|
+
def self.bind_random_port(udpsock, bind_host="0.0.0.0") # :nodoc:
|
|
675
|
+
udpsock.bind(bind_host, 0)
|
|
676
|
+
end
|
|
677
|
+
else
|
|
678
|
+
# Sequential port assignment
|
|
679
|
+
def self.bind_random_port(udpsock, bind_host="0.0.0.0") # :nodoc:
|
|
680
|
+
# Ephemeral port number range recommended by RFC 6056
|
|
664
681
|
port = random(1024..65535)
|
|
665
682
|
udpsock.bind(bind_host, port)
|
|
666
683
|
rescue Errno::EADDRINUSE, # POSIX
|
|
@@ -983,13 +1000,13 @@ class Resolv
|
|
|
983
1000
|
next unless keyword
|
|
984
1001
|
case keyword
|
|
985
1002
|
when 'nameserver'
|
|
986
|
-
nameserver.concat(args)
|
|
1003
|
+
nameserver.concat(args.each(&:freeze))
|
|
987
1004
|
when 'domain'
|
|
988
1005
|
next if args.empty?
|
|
989
|
-
search = [args[0]]
|
|
1006
|
+
search = [args[0].freeze]
|
|
990
1007
|
when 'search'
|
|
991
1008
|
next if args.empty?
|
|
992
|
-
search = args
|
|
1009
|
+
search = args.each(&:freeze)
|
|
993
1010
|
when 'options'
|
|
994
1011
|
args.each {|arg|
|
|
995
1012
|
case arg
|
|
@@ -1000,22 +1017,21 @@ class Resolv
|
|
|
1000
1017
|
end
|
|
1001
1018
|
}
|
|
1002
1019
|
}
|
|
1003
|
-
return { :nameserver => nameserver, :search => search, :ndots => ndots }
|
|
1020
|
+
return { :nameserver => nameserver.freeze, :search => search.freeze, :ndots => ndots.freeze }.freeze
|
|
1004
1021
|
end
|
|
1005
1022
|
|
|
1006
1023
|
def Config.default_config_hash(filename="/etc/resolv.conf")
|
|
1007
1024
|
if File.exist? filename
|
|
1008
|
-
|
|
1025
|
+
Config.parse_resolv_conf(filename)
|
|
1026
|
+
elsif defined?(Win32::Resolv)
|
|
1027
|
+
search, nameserver = Win32::Resolv.get_resolv_info
|
|
1028
|
+
config_hash = {}
|
|
1029
|
+
config_hash[:nameserver] = nameserver if nameserver
|
|
1030
|
+
config_hash[:search] = [search].flatten if search
|
|
1031
|
+
config_hash
|
|
1009
1032
|
else
|
|
1010
|
-
|
|
1011
|
-
require 'win32/resolv'
|
|
1012
|
-
search, nameserver = Win32::Resolv.get_resolv_info
|
|
1013
|
-
config_hash = {}
|
|
1014
|
-
config_hash[:nameserver] = nameserver if nameserver
|
|
1015
|
-
config_hash[:search] = [search].flatten if search
|
|
1016
|
-
end
|
|
1033
|
+
{}
|
|
1017
1034
|
end
|
|
1018
|
-
config_hash || {}
|
|
1019
1035
|
end
|
|
1020
1036
|
|
|
1021
1037
|
def lazy_initialize
|
|
@@ -1664,6 +1680,7 @@ class Resolv
|
|
|
1664
1680
|
prev_index = @index
|
|
1665
1681
|
save_index = nil
|
|
1666
1682
|
d = []
|
|
1683
|
+
size = -1
|
|
1667
1684
|
while true
|
|
1668
1685
|
raise DecodeError.new("limit exceeded") if @limit <= @index
|
|
1669
1686
|
case @data.getbyte(@index)
|
|
@@ -1684,7 +1701,10 @@ class Resolv
|
|
|
1684
1701
|
end
|
|
1685
1702
|
@index = idx
|
|
1686
1703
|
else
|
|
1687
|
-
|
|
1704
|
+
l = self.get_label
|
|
1705
|
+
d << l
|
|
1706
|
+
size += 1 + l.string.bytesize
|
|
1707
|
+
raise DecodeError.new("name label data exceed 255 octets") if size > 255
|
|
1688
1708
|
end
|
|
1689
1709
|
end
|
|
1690
1710
|
end
|
|
@@ -2110,7 +2130,14 @@ class Resolv
|
|
|
2110
2130
|
|
|
2111
2131
|
attr_reader :ttl
|
|
2112
2132
|
|
|
2113
|
-
ClassHash =
|
|
2133
|
+
ClassHash = Module.new do
|
|
2134
|
+
module_function
|
|
2135
|
+
|
|
2136
|
+
def []=(type_class_value, klass)
|
|
2137
|
+
type_value, class_value = type_class_value
|
|
2138
|
+
Resource.const_set(:"Type#{type_value}_Class#{class_value}", klass)
|
|
2139
|
+
end
|
|
2140
|
+
end
|
|
2114
2141
|
|
|
2115
2142
|
def encode_rdata(msg) # :nodoc:
|
|
2116
2143
|
raise NotImplementedError.new
|
|
@@ -2148,7 +2175,9 @@ class Resolv
|
|
|
2148
2175
|
end
|
|
2149
2176
|
|
|
2150
2177
|
def self.get_class(type_value, class_value) # :nodoc:
|
|
2151
|
-
|
|
2178
|
+
cache = :"Type#{type_value}_Class#{class_value}"
|
|
2179
|
+
|
|
2180
|
+
return (const_defined?(cache) && const_get(cache)) ||
|
|
2152
2181
|
Generic.create(type_value, class_value)
|
|
2153
2182
|
end
|
|
2154
2183
|
|
|
@@ -2577,7 +2606,7 @@ class Resolv
|
|
|
2577
2606
|
end
|
|
2578
2607
|
|
|
2579
2608
|
##
|
|
2580
|
-
# Flags for this
|
|
2609
|
+
# Flags for this property:
|
|
2581
2610
|
# - Bit 0 : 0 = not critical, 1 = critical
|
|
2582
2611
|
|
|
2583
2612
|
attr_reader :flags
|
|
@@ -2898,15 +2927,21 @@ class Resolv
|
|
|
2898
2927
|
|
|
2899
2928
|
class IPv4
|
|
2900
2929
|
|
|
2901
|
-
##
|
|
2902
|
-
# Regular expression IPv4 addresses must match.
|
|
2903
|
-
|
|
2904
2930
|
Regex256 = /0
|
|
2905
2931
|
|1(?:[0-9][0-9]?)?
|
|
2906
2932
|
|2(?:[0-4][0-9]?|5[0-5]?|[6-9])?
|
|
2907
|
-
|[3-9][0-9]?/x
|
|
2933
|
+
|[3-9][0-9]?/x # :nodoc:
|
|
2934
|
+
|
|
2935
|
+
##
|
|
2936
|
+
# Regular expression IPv4 addresses must match.
|
|
2908
2937
|
Regex = /\A(#{Regex256})\.(#{Regex256})\.(#{Regex256})\.(#{Regex256})\z/
|
|
2909
2938
|
|
|
2939
|
+
##
|
|
2940
|
+
# Creates a new IPv4 address from +arg+ which may be:
|
|
2941
|
+
#
|
|
2942
|
+
# IPv4:: returns +arg+.
|
|
2943
|
+
# String:: +arg+ must match the IPv4::Regex constant
|
|
2944
|
+
|
|
2910
2945
|
def self.create(arg)
|
|
2911
2946
|
case arg
|
|
2912
2947
|
when IPv4
|
|
@@ -3215,13 +3250,15 @@ class Resolv
|
|
|
3215
3250
|
|
|
3216
3251
|
end
|
|
3217
3252
|
|
|
3218
|
-
module LOC
|
|
3253
|
+
module LOC # :nodoc:
|
|
3219
3254
|
|
|
3220
3255
|
##
|
|
3221
3256
|
# A Resolv::LOC::Size
|
|
3222
3257
|
|
|
3223
3258
|
class Size
|
|
3224
3259
|
|
|
3260
|
+
# Regular expression LOC size must match.
|
|
3261
|
+
|
|
3225
3262
|
Regex = /^(\d+\.*\d*)[m]$/
|
|
3226
3263
|
|
|
3227
3264
|
##
|
|
@@ -3247,6 +3284,7 @@ class Resolv
|
|
|
3247
3284
|
end
|
|
3248
3285
|
end
|
|
3249
3286
|
|
|
3287
|
+
# Internal use; use self.create.
|
|
3250
3288
|
def initialize(scalar)
|
|
3251
3289
|
@scalar = scalar
|
|
3252
3290
|
end
|
|
@@ -3284,6 +3322,8 @@ class Resolv
|
|
|
3284
3322
|
|
|
3285
3323
|
class Coord
|
|
3286
3324
|
|
|
3325
|
+
# Regular expression LOC Coord must match.
|
|
3326
|
+
|
|
3287
3327
|
Regex = /^(\d+)\s(\d+)\s(\d+\.\d+)\s([NESW])$/
|
|
3288
3328
|
|
|
3289
3329
|
##
|
|
@@ -3313,6 +3353,7 @@ class Resolv
|
|
|
3313
3353
|
end
|
|
3314
3354
|
end
|
|
3315
3355
|
|
|
3356
|
+
# Internal use; use self.create.
|
|
3316
3357
|
def initialize(coordinates,orientation)
|
|
3317
3358
|
unless coordinates.kind_of?(String)
|
|
3318
3359
|
raise ArgumentError.new("Coord must be a 32bit unsigned integer in hex format: #{coordinates.inspect}")
|
|
@@ -3375,6 +3416,8 @@ class Resolv
|
|
|
3375
3416
|
|
|
3376
3417
|
class Alt
|
|
3377
3418
|
|
|
3419
|
+
# Regular expression LOC Alt must match.
|
|
3420
|
+
|
|
3378
3421
|
Regex = /^([+-]*\d+\.*\d*)[m]$/
|
|
3379
3422
|
|
|
3380
3423
|
##
|
|
@@ -3400,6 +3443,7 @@ class Resolv
|
|
|
3400
3443
|
end
|
|
3401
3444
|
end
|
|
3402
3445
|
|
|
3446
|
+
# Internal use; use self.create.
|
|
3403
3447
|
def initialize(altitude)
|
|
3404
3448
|
@altitude = altitude
|
|
3405
3449
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: resolv
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.7.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tanaka Akira
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: exe
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies: []
|
|
13
12
|
description: Thread-aware DNS resolver library in Ruby.
|
|
14
13
|
email:
|
|
@@ -18,23 +17,14 @@ extensions:
|
|
|
18
17
|
- ext/win32/resolv/extconf.rb
|
|
19
18
|
extra_rdoc_files: []
|
|
20
19
|
files:
|
|
21
|
-
- ".
|
|
22
|
-
- ".github/dependabot.yml"
|
|
23
|
-
- ".github/workflows/push_gem.yml"
|
|
24
|
-
- ".github/workflows/test.yml"
|
|
25
|
-
- ".gitignore"
|
|
20
|
+
- ".document"
|
|
26
21
|
- BSDL
|
|
27
22
|
- COPYING
|
|
28
|
-
- Gemfile
|
|
29
23
|
- README.md
|
|
30
|
-
- Rakefile
|
|
31
|
-
- bin/console
|
|
32
|
-
- bin/setup
|
|
33
24
|
- ext/win32/resolv/extconf.rb
|
|
34
25
|
- ext/win32/resolv/lib/resolv.rb
|
|
35
26
|
- ext/win32/resolv/resolv.c
|
|
36
27
|
- lib/resolv.rb
|
|
37
|
-
- resolv.gemspec
|
|
38
28
|
homepage: https://github.com/ruby/resolv
|
|
39
29
|
licenses:
|
|
40
30
|
- Ruby
|
|
@@ -42,7 +32,6 @@ licenses:
|
|
|
42
32
|
metadata:
|
|
43
33
|
homepage_uri: https://github.com/ruby/resolv
|
|
44
34
|
source_code_uri: https://github.com/ruby/resolv
|
|
45
|
-
post_install_message:
|
|
46
35
|
rdoc_options: []
|
|
47
36
|
require_paths:
|
|
48
37
|
- lib
|
|
@@ -57,8 +46,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
57
46
|
- !ruby/object:Gem::Version
|
|
58
47
|
version: '0'
|
|
59
48
|
requirements: []
|
|
60
|
-
rubygems_version: 3.
|
|
61
|
-
signing_key:
|
|
49
|
+
rubygems_version: 3.6.9
|
|
62
50
|
specification_version: 4
|
|
63
51
|
summary: Thread-aware DNS resolver library in Ruby.
|
|
64
52
|
test_files: []
|
data/.git-blame-ignore-revs
DELETED
|
@@ -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
|
data/.github/dependabot.yml
DELETED
|
@@ -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@0080882f6c36860b6ba35c610c98ce87d4e2f26f # v2.10.2
|
|
27
|
-
with:
|
|
28
|
-
egress-policy: audit
|
|
29
|
-
|
|
30
|
-
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
|
|
31
|
-
|
|
32
|
-
- name: Set up Ruby
|
|
33
|
-
uses: ruby/setup-ruby@a6e6f86333f0a2523ece813039b8b4be04560854 # v1.190.0
|
|
34
|
-
with:
|
|
35
|
-
bundler-cache: true
|
|
36
|
-
ruby-version: ruby
|
|
37
|
-
|
|
38
|
-
- name: Publish to RubyGems
|
|
39
|
-
uses: rubygems/release-gem@9e85cb11501bebc2ae661c1500176316d3987059 # v1.1.0
|
|
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.MATZBOT_GITHUB_WORKFLOW_TOKEN }}
|
data/.github/workflows/test.yml
DELETED
|
@@ -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@v4
|
|
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
data/Gemfile
DELETED
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
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
|