resolv 0.6.2 → 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/ext/win32/resolv/extconf.rb +2 -1
- data/ext/win32/resolv/lib/resolv.rb +47 -85
- data/ext/win32/resolv/resolv.c +203 -10
- data/lib/resolv.rb +30 -14
- metadata +3 -12
- 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 -11
- 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/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,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,115 +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
|
|
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
|
-
|
|
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
|
-
|
|
78
|
-
|
|
60
|
+
tcpip_params do |params|
|
|
61
|
+
slist = params.value('SearchList')
|
|
62
|
+
search = slist.split(/,\s*/) if slist and !slist.empty?
|
|
79
63
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
64
|
+
if add_search = search.nil?
|
|
65
|
+
search = []
|
|
66
|
+
domain = params.value('Domain')
|
|
83
67
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
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
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
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
|
-
|
|
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
|
|
86
|
+
next if (nameserver & ns).empty?
|
|
112
87
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
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
|
-
|
|
130
|
-
if defined?(Win32::Registry)
|
|
131
|
-
Registry::HKEY_LOCAL_MACHINE.open(path) do |reg|
|
|
132
|
-
expand ? reg.read_s_expand(name) : reg.read_s(name)
|
|
133
|
-
rescue Registry::Error
|
|
134
|
-
""
|
|
135
|
-
end
|
|
136
|
-
else
|
|
137
|
-
cmd = "Get-ItemProperty -Path 'HKLM:\\#{path}' -Name '#{name}' -ErrorAction SilentlyContinue | Select-Object -ExpandProperty '#{name}'"
|
|
138
|
-
output, _ = Open3.capture2('powershell', '-Command', cmd)
|
|
139
|
-
output.strip
|
|
100
|
+
search << devo if add_search and devo
|
|
140
101
|
end
|
|
102
|
+
[ search.uniq, nameserver.uniq ]
|
|
141
103
|
end
|
|
142
104
|
end
|
|
143
105
|
end
|
data/ext/win32/resolv/resolv.c
CHANGED
|
@@ -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
|
-
|
|
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
|
-
NORETURN(static void w32error_raise(DWORD e));
|
|
17
|
-
|
|
18
39
|
static void
|
|
19
|
-
|
|
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
|
-
|
|
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 !=
|
|
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
|
-
|
|
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
|
@@ -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+.
|
|
@@ -173,21 +175,19 @@ class Resolv
|
|
|
173
175
|
|
|
174
176
|
class ResolvTimeout < Timeout::Error; end
|
|
175
177
|
|
|
176
|
-
WINDOWS = /mswin|cygwin|mingw|bccwin/ =~ RUBY_PLATFORM || ::RbConfig::CONFIG['host_os'] =~ /mswin/
|
|
177
|
-
private_constant :WINDOWS
|
|
178
|
-
|
|
179
178
|
##
|
|
180
179
|
# Resolv::Hosts is a hostname resolver that uses the system hosts file.
|
|
181
180
|
|
|
182
181
|
class Hosts
|
|
183
|
-
if
|
|
182
|
+
if /mswin|cygwin|mingw|bccwin/ =~ RUBY_PLATFORM || ::RbConfig::CONFIG['host_os'] =~ /mswin/
|
|
184
183
|
begin
|
|
185
184
|
require 'win32/resolv' unless defined?(Win32::Resolv)
|
|
186
|
-
|
|
185
|
+
hosts = Win32::Resolv.get_hosts_path || IO::NULL
|
|
187
186
|
rescue LoadError
|
|
188
187
|
end
|
|
189
188
|
end
|
|
190
|
-
|
|
189
|
+
# The default file name for host names
|
|
190
|
+
DefaultFileName = hosts || '/etc/hosts'
|
|
191
191
|
|
|
192
192
|
##
|
|
193
193
|
# Creates a new Resolv::Hosts, using +filename+ for its data source.
|
|
@@ -525,6 +525,8 @@ class Resolv
|
|
|
525
525
|
}
|
|
526
526
|
end
|
|
527
527
|
|
|
528
|
+
# :stopdoc:
|
|
529
|
+
|
|
528
530
|
def fetch_resource(name, typeclass)
|
|
529
531
|
lazy_initialize
|
|
530
532
|
truncated = {}
|
|
@@ -1021,8 +1023,7 @@ class Resolv
|
|
|
1021
1023
|
def Config.default_config_hash(filename="/etc/resolv.conf")
|
|
1022
1024
|
if File.exist? filename
|
|
1023
1025
|
Config.parse_resolv_conf(filename)
|
|
1024
|
-
elsif
|
|
1025
|
-
require 'win32/resolv' unless defined?(Win32::Resolv)
|
|
1026
|
+
elsif defined?(Win32::Resolv)
|
|
1026
1027
|
search, nameserver = Win32::Resolv.get_resolv_info
|
|
1027
1028
|
config_hash = {}
|
|
1028
1029
|
config_hash[:nameserver] = nameserver if nameserver
|
|
@@ -2926,15 +2927,21 @@ class Resolv
|
|
|
2926
2927
|
|
|
2927
2928
|
class IPv4
|
|
2928
2929
|
|
|
2929
|
-
##
|
|
2930
|
-
# Regular expression IPv4 addresses must match.
|
|
2931
|
-
|
|
2932
2930
|
Regex256 = /0
|
|
2933
2931
|
|1(?:[0-9][0-9]?)?
|
|
2934
2932
|
|2(?:[0-4][0-9]?|5[0-5]?|[6-9])?
|
|
2935
|
-
|[3-9][0-9]?/x
|
|
2933
|
+
|[3-9][0-9]?/x # :nodoc:
|
|
2934
|
+
|
|
2935
|
+
##
|
|
2936
|
+
# Regular expression IPv4 addresses must match.
|
|
2936
2937
|
Regex = /\A(#{Regex256})\.(#{Regex256})\.(#{Regex256})\.(#{Regex256})\z/
|
|
2937
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
|
+
|
|
2938
2945
|
def self.create(arg)
|
|
2939
2946
|
case arg
|
|
2940
2947
|
when IPv4
|
|
@@ -3243,13 +3250,15 @@ class Resolv
|
|
|
3243
3250
|
|
|
3244
3251
|
end
|
|
3245
3252
|
|
|
3246
|
-
module LOC
|
|
3253
|
+
module LOC # :nodoc:
|
|
3247
3254
|
|
|
3248
3255
|
##
|
|
3249
3256
|
# A Resolv::LOC::Size
|
|
3250
3257
|
|
|
3251
3258
|
class Size
|
|
3252
3259
|
|
|
3260
|
+
# Regular expression LOC size must match.
|
|
3261
|
+
|
|
3253
3262
|
Regex = /^(\d+\.*\d*)[m]$/
|
|
3254
3263
|
|
|
3255
3264
|
##
|
|
@@ -3275,6 +3284,7 @@ class Resolv
|
|
|
3275
3284
|
end
|
|
3276
3285
|
end
|
|
3277
3286
|
|
|
3287
|
+
# Internal use; use self.create.
|
|
3278
3288
|
def initialize(scalar)
|
|
3279
3289
|
@scalar = scalar
|
|
3280
3290
|
end
|
|
@@ -3312,6 +3322,8 @@ class Resolv
|
|
|
3312
3322
|
|
|
3313
3323
|
class Coord
|
|
3314
3324
|
|
|
3325
|
+
# Regular expression LOC Coord must match.
|
|
3326
|
+
|
|
3315
3327
|
Regex = /^(\d+)\s(\d+)\s(\d+\.\d+)\s([NESW])$/
|
|
3316
3328
|
|
|
3317
3329
|
##
|
|
@@ -3341,6 +3353,7 @@ class Resolv
|
|
|
3341
3353
|
end
|
|
3342
3354
|
end
|
|
3343
3355
|
|
|
3356
|
+
# Internal use; use self.create.
|
|
3344
3357
|
def initialize(coordinates,orientation)
|
|
3345
3358
|
unless coordinates.kind_of?(String)
|
|
3346
3359
|
raise ArgumentError.new("Coord must be a 32bit unsigned integer in hex format: #{coordinates.inspect}")
|
|
@@ -3403,6 +3416,8 @@ class Resolv
|
|
|
3403
3416
|
|
|
3404
3417
|
class Alt
|
|
3405
3418
|
|
|
3419
|
+
# Regular expression LOC Alt must match.
|
|
3420
|
+
|
|
3406
3421
|
Regex = /^([+-]*\d+\.*\d*)[m]$/
|
|
3407
3422
|
|
|
3408
3423
|
##
|
|
@@ -3428,6 +3443,7 @@ class Resolv
|
|
|
3428
3443
|
end
|
|
3429
3444
|
end
|
|
3430
3445
|
|
|
3446
|
+
# Internal use; use self.create.
|
|
3431
3447
|
def initialize(altitude)
|
|
3432
3448
|
@altitude = altitude
|
|
3433
3449
|
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.
|
|
4
|
+
version: 0.7.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tanaka Akira
|
|
@@ -17,23 +17,14 @@ extensions:
|
|
|
17
17
|
- ext/win32/resolv/extconf.rb
|
|
18
18
|
extra_rdoc_files: []
|
|
19
19
|
files:
|
|
20
|
-
- ".
|
|
21
|
-
- ".github/dependabot.yml"
|
|
22
|
-
- ".github/workflows/push_gem.yml"
|
|
23
|
-
- ".github/workflows/test.yml"
|
|
24
|
-
- ".gitignore"
|
|
20
|
+
- ".document"
|
|
25
21
|
- BSDL
|
|
26
22
|
- COPYING
|
|
27
|
-
- Gemfile
|
|
28
23
|
- README.md
|
|
29
|
-
- Rakefile
|
|
30
|
-
- bin/console
|
|
31
|
-
- bin/setup
|
|
32
24
|
- ext/win32/resolv/extconf.rb
|
|
33
25
|
- ext/win32/resolv/lib/resolv.rb
|
|
34
26
|
- ext/win32/resolv/resolv.c
|
|
35
27
|
- lib/resolv.rb
|
|
36
|
-
- resolv.gemspec
|
|
37
28
|
homepage: https://github.com/ruby/resolv
|
|
38
29
|
licenses:
|
|
39
30
|
- Ruby
|
|
@@ -55,7 +46,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
55
46
|
- !ruby/object:Gem::Version
|
|
56
47
|
version: '0'
|
|
57
48
|
requirements: []
|
|
58
|
-
rubygems_version: 3.6.
|
|
49
|
+
rubygems_version: 3.6.9
|
|
59
50
|
specification_version: 4
|
|
60
51
|
summary: Thread-aware DNS resolver library in Ruby.
|
|
61
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@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2
|
|
27
|
-
with:
|
|
28
|
-
egress-policy: audit
|
|
29
|
-
|
|
30
|
-
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
31
|
-
|
|
32
|
-
- name: Set up Ruby
|
|
33
|
-
uses: ruby/setup-ruby@a4effe49ee8ee5b8b5091268c473a4628afb5651 # v1.245.0
|
|
34
|
-
with:
|
|
35
|
-
bundler-cache: true
|
|
36
|
-
ruby-version: ruby
|
|
37
|
-
|
|
38
|
-
- name: Publish to RubyGems
|
|
39
|
-
uses: rubygems/release-gem@a25424ba2ba8b387abc8ef40807c2c85b96cbe32 # v1.1.1
|
|
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 }}
|
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
|