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 +4 -4
- data/.document +4 -0
- data/ext/win32/resolv/extconf.rb +1 -0
- data/ext/win32/resolv/lib/resolv.rb +47 -91
- data/ext/win32/resolv/resolv.c +203 -10
- data/lib/resolv.rb +40 -16
- metadata +2 -13
- data/.git-blame-ignore-revs +0 -7
- data/.github/dependabot.yml +0 -6
- data/.github/release.yml +0 -4
- data/.github/workflows/push_gem.yml +0 -46
- data/.github/workflows/sync-ruby.yml +0 -33
- 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: c4c4e60f6c23abc6f116dfbea5e531d20f99eb85025e4682d3d85f580e17d09d
|
|
4
|
+
data.tar.gz: e609b5a2a67f67b5d7c616a2a3340d5ab3af305a29f66ab800785d62466ab883
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3eab1f21df971bd56cd9e23429fdef5da84a502c6d441dcf4cb3ff06fbf2c5222c7cd72b6d17a466d46b956bdeeeecfde0bc0254d78c37d73d1fd1c915bc0912
|
|
7
|
+
data.tar.gz: e81e097c7fc424ba72f2f84a07d933cb7bfb001f019ba2babb440c2a94e5aed2f38df688934cd0a35a5ed583ae73969b56ea7e6a92f1e8cdf4875a210d331003
|
data/.document
ADDED
data/ext/win32/resolv/extconf.rb
CHANGED
|
@@ -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
|
-
|
|
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
|
|
112
|
-
|
|
113
|
-
next if (nameserver & ns).empty?
|
|
86
|
+
next if (nameserver & ns).empty?
|
|
114
87
|
|
|
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
|
-
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
|
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
|
@@ -34,7 +34,8 @@ require 'rbconfig'
|
|
|
34
34
|
|
|
35
35
|
class Resolv
|
|
36
36
|
|
|
37
|
-
|
|
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
|
|
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
|
-
|
|
185
|
+
hosts = Win32::Resolv.get_hosts_path || IO::NULL
|
|
188
186
|
rescue LoadError
|
|
189
187
|
end
|
|
190
188
|
end
|
|
191
|
-
|
|
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
|
-
|
|
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
|
|
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.
|
|
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
|
-
- ".
|
|
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
|
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
data/.github/release.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@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
|
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@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
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
|