YkLib 0.1.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 +7 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/.travis.yml +6 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +7 -0
- data/Gemfile.lock +34 -0
- data/LICENSE.txt +21 -0
- data/README.md +44 -0
- data/Rakefile +6 -0
- data/YkLib.gemspec +29 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/YkLib/Yk/__advance__.rb +151 -0
- data/lib/YkLib/Yk/__defun__.rb +44 -0
- data/lib/YkLib/Yk/__hook__.rb +244 -0
- data/lib/YkLib/Yk/__minmax__.rb +123 -0
- data/lib/YkLib/Yk/__stdlog.rb +329 -0
- data/lib/YkLib/Yk/adhocLiterals/email.rb +119 -0
- data/lib/YkLib/Yk/adhocLiterals/path.rb +402 -0
- data/lib/YkLib/Yk/adhocLiterals/tag.rb +19 -0
- data/lib/YkLib/Yk/adhocLiterals/url.rb +36 -0
- data/lib/YkLib/Yk/adhocLiterals.rb +199 -0
- data/lib/YkLib/Yk/auto_escseq.rb +5 -0
- data/lib/YkLib/Yk/auto_pstore.rb +179 -0
- data/lib/YkLib/Yk/bsearch.rb +120 -0
- data/lib/YkLib/Yk/clambda.rb +309 -0
- data/lib/YkLib/Yk/confLine.rb +423 -0
- data/lib/YkLib/Yk/create_tty_width_available.rb +24 -0
- data/lib/YkLib/Yk/crypt.rb +26 -0
- data/lib/YkLib/Yk/debug2 +1 -0
- data/lib/YkLib/Yk/debug2.rb +473 -0
- data/lib/YkLib/Yk/debugout.rb +139 -0
- data/lib/YkLib/Yk/email_tz.rb +533 -0
- data/lib/YkLib/Yk/enum_expect.rb +170 -0
- data/lib/YkLib/Yk/errlog.rb +5 -0
- data/lib/YkLib/Yk/escseq.rb +59 -0
- data/lib/YkLib/Yk/eval_alt.rb +281 -0
- data/lib/YkLib/Yk/expector.rb +93 -0
- data/lib/YkLib/Yk/fetch.rb +556 -0
- data/lib/YkLib/Yk/fetch_old.rb +290 -0
- data/lib/YkLib/Yk/fib.rb +158 -0
- data/lib/YkLib/Yk/file_aux.rb +843 -0
- data/lib/YkLib/Yk/file_aux2.rb +919 -0
- data/lib/YkLib/Yk/file_aux_old.rb +160 -0
- data/lib/YkLib/Yk/filemod.rb +19 -0
- data/lib/YkLib/Yk/force_escseq.rb +3 -0
- data/lib/YkLib/Yk/generator__.rb +144 -0
- data/lib/YkLib/Yk/generator__.rb.org +139 -0
- data/lib/YkLib/Yk/indenter/argless_case.rb +46 -0
- data/lib/YkLib/Yk/indenter/each_token.rb +671 -0
- data/lib/YkLib/Yk/indenter/free_case.rb +313 -0
- data/lib/YkLib/Yk/indenter/if_less.rb +53 -0
- data/lib/YkLib/Yk/indenter/independent_ensure.rb +23 -0
- data/lib/YkLib/Yk/indenter/independent_rescue.rb +23 -0
- data/lib/YkLib/Yk/indenter/operand_circumflex.rb +0 -0
- data/lib/YkLib/Yk/indenter/operand_period.rb +16 -0
- data/lib/YkLib/Yk/indenter/parenless_and.rb +37 -0
- data/lib/YkLib/Yk/indenter/post_test.rb +48 -0
- data/lib/YkLib/Yk/indenter/token.rb +1525 -0
- data/lib/YkLib/Yk/indenter.rb +1382 -0
- data/lib/YkLib/Yk/inot.rb +265 -0
- data/lib/YkLib/Yk/intf.rb +815 -0
- data/lib/YkLib/Yk/io_aux.rb +1332 -0
- data/lib/YkLib/Yk/ioctl.rb +60 -0
- data/lib/YkLib/Yk/ipcc.rb +87 -0
- data/lib/YkLib/Yk/ipcountry.rb +207 -0
- data/lib/YkLib/Yk/ipv4adr.rb +318 -0
- data/lib/YkLib/Yk/localmail.rb +276 -0
- data/lib/YkLib/Yk/method_chain.rb +359 -0
- data/lib/YkLib/Yk/misc_tz.rb +1716 -0
- data/lib/YkLib/Yk/missing_method.rb +50 -0
- data/lib/YkLib/Yk/mojiConv.rb +257 -0
- data/lib/YkLib/Yk/nostdlog.rb +4 -0
- data/lib/YkLib/Yk/on_marshal.rb +20 -0
- data/lib/YkLib/Yk/overrider.rb +47 -0
- data/lib/YkLib/Yk/path.rb +293 -0
- data/lib/YkLib/Yk/path_aux.rb +883 -0
- data/lib/YkLib/Yk/path_aux_alt.rb +0 -0
- data/lib/YkLib/Yk/path_rep.rb +1267 -0
- data/lib/YkLib/Yk/pg_setup.rb +917 -0
- data/lib/YkLib/Yk/procinfo.rb +314 -0
- data/lib/YkLib/Yk/proclist.rb +492 -0
- data/lib/YkLib/Yk/property.rb +863 -0
- data/lib/YkLib/Yk/ranger.rb +606 -0
- data/lib/YkLib/Yk/resolv_tz.rb +88 -0
- data/lib/YkLib/Yk/rlprompt.rb +73 -0
- data/lib/YkLib/Yk/rootexec.rb +48 -0
- data/lib/YkLib/Yk/rpm-packageproxy.rb +784 -0
- data/lib/YkLib/Yk/rpm-packageproxy2.rb +1430 -0
- data/lib/YkLib/Yk/rwhen.rb +21 -0
- data/lib/YkLib/Yk/selector.rb +124 -0
- data/lib/YkLib/Yk/set.rb +170 -0
- data/lib/YkLib/Yk/shellquote.rb +300 -0
- data/lib/YkLib/Yk/sio.rb +1001 -0
- data/lib/YkLib/Yk/sio0.rb +835 -0
- data/lib/YkLib/Yk/sio_aux.rb +1524 -0
- data/lib/YkLib/Yk/sio_inot.rb +86 -0
- data/lib/YkLib/Yk/sock_aux.rb +42 -0
- data/lib/YkLib/Yk/spipe.rb +843 -0
- data/lib/YkLib/Yk/sql_table.rb +565 -0
- data/lib/YkLib/Yk/stdlog.rb +4 -0
- data/lib/YkLib/Yk/syscommand.rb +173 -0
- data/lib/YkLib/Yk/sysinit.rb +75 -0
- data/lib/YkLib/Yk/ttyFontWidth.rb +46113 -0
- data/lib/YkLib/Yk/tty_char.dump +0 -0
- data/lib/YkLib/Yk/tty_char.rb +47 -0
- data/lib/YkLib/Yk/tty_char_create.rb +437031 -0
- data/lib/YkLib/Yk/tty_char_static.rb +437016 -0
- data/lib/YkLib/Yk/tty_rewrite.rb +142 -0
- data/lib/YkLib/Yk/tty_str.rb +461 -0
- data/lib/YkLib/Yk/tty_width.dat.rb +114 -0
- data/lib/YkLib/Yk/tty_width.rb +180 -0
- data/lib/YkLib/Yk/tty_width_available +569 -0
- data/lib/YkLib/Yk/tty_width_list +0 -0
- data/lib/YkLib/Yk/tty_width_list.linux +280 -0
- data/lib/YkLib/Yk/tty_width_list.windows +324 -0
- data/lib/YkLib/Yk/tz_tty +0 -0
- data/lib/YkLib/Yk/tz_tty.rb +0 -0
- data/lib/YkLib/Yk/uprepos.rb +94 -0
- data/lib/YkLib/Yk/userinfo.rb +91 -0
- data/lib/YkLib/Yk/with.rb +109 -0
- data/lib/YkLib/version.rb +3 -0
- data/lib/YkLib.rb +6 -0
- metadata +170 -0
data/lib/YkLib/Yk/sio.rb
ADDED
|
@@ -0,0 +1,1001 @@
|
|
|
1
|
+
require 'Yk/path_aux'
|
|
2
|
+
require 'net/smtp'
|
|
3
|
+
require 'base64'
|
|
4
|
+
require 'uri'
|
|
5
|
+
require 'net/dns'
|
|
6
|
+
require 'socket'
|
|
7
|
+
require 'cgi'
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
#p > nil
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
IPv4Regexp = /^(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class IO
|
|
17
|
+
def set_sio mode = nil
|
|
18
|
+
@sio = SIO.new self, mode
|
|
19
|
+
end
|
|
20
|
+
def sio
|
|
21
|
+
@sio
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class String
|
|
27
|
+
SIOServers = Hash.new
|
|
28
|
+
TCPConnectTimeout = 1
|
|
29
|
+
def to_ip
|
|
30
|
+
SIOResolver.resolv self
|
|
31
|
+
end
|
|
32
|
+
def __open tmode, &prc
|
|
33
|
+
self =~ /:/
|
|
34
|
+
adr, port = $`, $'
|
|
35
|
+
a = adr
|
|
36
|
+
p adr
|
|
37
|
+
if adr !~ /^(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/
|
|
38
|
+
p
|
|
39
|
+
adr = adr.to_ip
|
|
40
|
+
p
|
|
41
|
+
end
|
|
42
|
+
if !adr
|
|
43
|
+
raise Exception.new("cannot resolv address: #{a}")
|
|
44
|
+
end
|
|
45
|
+
p adr
|
|
46
|
+
s = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
|
|
47
|
+
sock_addr = Socket.sockaddr_in(port, adr)
|
|
48
|
+
s.set_sio tmode
|
|
49
|
+
s.connect_nonblock(sock_addr) rescue IO::WaitWritable
|
|
50
|
+
SIO.select s.sio, :write, TCPConnectTimeout
|
|
51
|
+
opt = s.getsockopt(Socket::SOL_SOCKET, Socket::SO_ERROR)
|
|
52
|
+
p opt
|
|
53
|
+
if opt.int != 0
|
|
54
|
+
s.close
|
|
55
|
+
raise SystemCallError.new(opt.int)
|
|
56
|
+
end
|
|
57
|
+
if prc
|
|
58
|
+
begin
|
|
59
|
+
prc.call s.sio
|
|
60
|
+
ensure
|
|
61
|
+
s.sio.close
|
|
62
|
+
end
|
|
63
|
+
else
|
|
64
|
+
s.sio
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
def open_T &prc
|
|
68
|
+
__open :text, &prc
|
|
69
|
+
end
|
|
70
|
+
def open &prc
|
|
71
|
+
__open :binary, &prc
|
|
72
|
+
end
|
|
73
|
+
def __listen tmode, &prc
|
|
74
|
+
self =~ /:/
|
|
75
|
+
adr, port = $`, $'
|
|
76
|
+
a = adr
|
|
77
|
+
if adr !~ /^(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/
|
|
78
|
+
adr = adr.to_ip
|
|
79
|
+
end
|
|
80
|
+
if !adr
|
|
81
|
+
raise Exception.new("cannot resolv address: #{a}")
|
|
82
|
+
end
|
|
83
|
+
sio = nil
|
|
84
|
+
begin
|
|
85
|
+
p adr, port
|
|
86
|
+
sio = (SIOServers[self] ||= SIO.new(TCPServer.new(adr, port.to_i)))
|
|
87
|
+
loop do
|
|
88
|
+
p
|
|
89
|
+
SIO.select sio, :read
|
|
90
|
+
p
|
|
91
|
+
as = sio.io.accept
|
|
92
|
+
esio = SIO.new as, tmode
|
|
93
|
+
SIO.fork do
|
|
94
|
+
p
|
|
95
|
+
begin
|
|
96
|
+
p
|
|
97
|
+
yield esio
|
|
98
|
+
p
|
|
99
|
+
ensure
|
|
100
|
+
esio.close
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
p
|
|
104
|
+
end
|
|
105
|
+
ensure
|
|
106
|
+
p $!
|
|
107
|
+
sio.close
|
|
108
|
+
SIOServers.delete self
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
def accept &prc
|
|
112
|
+
__listen :binary, &prc
|
|
113
|
+
end
|
|
114
|
+
def accept_T &prc
|
|
115
|
+
__listen :text, &prc
|
|
116
|
+
end
|
|
117
|
+
def url_encode
|
|
118
|
+
CGI.escape self
|
|
119
|
+
end
|
|
120
|
+
def url_decode
|
|
121
|
+
CGI.unescape self
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
class Integer
|
|
127
|
+
def accept &prc
|
|
128
|
+
"0.0.0.0:#{self}".accept &prc
|
|
129
|
+
end
|
|
130
|
+
def accept_T &prc
|
|
131
|
+
"0.0.0.0:#{self}".accept_T &prc
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def local *args
|
|
137
|
+
yield *args
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
class SIO
|
|
142
|
+
class ExpectException < Exception
|
|
143
|
+
end
|
|
144
|
+
attr :io
|
|
145
|
+
def initialize io, m = :binary
|
|
146
|
+
@io = io
|
|
147
|
+
@mode = m
|
|
148
|
+
@readBuff = ""
|
|
149
|
+
@residue = ""
|
|
150
|
+
end
|
|
151
|
+
def expect arg
|
|
152
|
+
arg = arg.lstrip
|
|
153
|
+
if arg == ""
|
|
154
|
+
return
|
|
155
|
+
end
|
|
156
|
+
loop do
|
|
157
|
+
@readBuff.lstrip!
|
|
158
|
+
break if @readBuff.size > 0
|
|
159
|
+
pre_read
|
|
160
|
+
end
|
|
161
|
+
p @readBuff
|
|
162
|
+
while @readBuff.size < arg.size && @readBuff == arg[0...@readBuff.size] && !@eof
|
|
163
|
+
pre_read
|
|
164
|
+
end
|
|
165
|
+
if @readBuff.size < arg.size
|
|
166
|
+
raise ExpectException.new "expected '#{arg}', but '#{@readBuff}' returned\n"
|
|
167
|
+
else
|
|
168
|
+
p @readBuff[0...arg.size]
|
|
169
|
+
p arg
|
|
170
|
+
p @readBuff[0...arg.size] != arg
|
|
171
|
+
if @readBuff[0...arg.size] != arg
|
|
172
|
+
raise ExpectException.new "expected '#{arg}', but '#{@readBuff}' returned\n"
|
|
173
|
+
end
|
|
174
|
+
@readBuff = @readBuff[arg.size ... @readBuff.size]
|
|
175
|
+
p @readBuff
|
|
176
|
+
return arg
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
def expectln arg = nil
|
|
180
|
+
if arg
|
|
181
|
+
expect arg + "\n"
|
|
182
|
+
else
|
|
183
|
+
loop do
|
|
184
|
+
if @readBuff.size == 0
|
|
185
|
+
if !@eof
|
|
186
|
+
pre_read
|
|
187
|
+
else
|
|
188
|
+
raise ExpectException.new "expected empty new line but reached eof\n"
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
if @eof
|
|
192
|
+
if @readBuff !~ /^[\t\f\r ]*\n/
|
|
193
|
+
if @readBuff.size == 0
|
|
194
|
+
raise ExpectException.new "expected empty new line but reached eof\n"
|
|
195
|
+
else
|
|
196
|
+
raise ExpectException.new "expected empty new line but read '#{@readBuff}'\n"
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
@readBuff = $'
|
|
200
|
+
while @readBuff =~ /^[\t\f\r ]*\n/
|
|
201
|
+
@readBuff = $'
|
|
202
|
+
end
|
|
203
|
+
return
|
|
204
|
+
else
|
|
205
|
+
while @readBuff =~ /^[\t\f\r ]+/
|
|
206
|
+
@readBuff = $'
|
|
207
|
+
if @readBuff.size == 0
|
|
208
|
+
pre_read
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
if @eof && @readBuff == ""
|
|
212
|
+
raise ExpectException.new "expected empty new line but reached eof\n"
|
|
213
|
+
end
|
|
214
|
+
if @readBuff[0] != "\n"
|
|
215
|
+
raise ExpectException.new "expected empty new line but read '#{@readBuff}'\n"
|
|
216
|
+
end
|
|
217
|
+
@readBuff = @readBuff[1...@readBuff.size]
|
|
218
|
+
loop do
|
|
219
|
+
while @readBuff =~ /^[\t\f\r ]+/
|
|
220
|
+
if $'.size > 0
|
|
221
|
+
break
|
|
222
|
+
elsif @eof # $'.size == 0
|
|
223
|
+
return
|
|
224
|
+
end
|
|
225
|
+
pre_read
|
|
226
|
+
end
|
|
227
|
+
if @readBuff[0] == "\n"
|
|
228
|
+
@readBuff = @readBuff[1...@readBuff.size]
|
|
229
|
+
next
|
|
230
|
+
end
|
|
231
|
+
return
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
def readline
|
|
238
|
+
idx = nil
|
|
239
|
+
res = @readBuff
|
|
240
|
+
@readBuff = ""
|
|
241
|
+
while !(idx = res.index "\n") && !@eof
|
|
242
|
+
pre_read
|
|
243
|
+
res += @readBuff
|
|
244
|
+
@readBuff = ""
|
|
245
|
+
end
|
|
246
|
+
p idx
|
|
247
|
+
if idx
|
|
248
|
+
ret = res[0..idx]
|
|
249
|
+
@readBuff = res[idx + 1 ... res.size]
|
|
250
|
+
else
|
|
251
|
+
ret = res
|
|
252
|
+
end
|
|
253
|
+
ret
|
|
254
|
+
end
|
|
255
|
+
def read_each_line
|
|
256
|
+
p
|
|
257
|
+
loop do
|
|
258
|
+
p
|
|
259
|
+
ret = readline
|
|
260
|
+
if ret != ""
|
|
261
|
+
yield ret
|
|
262
|
+
end
|
|
263
|
+
if @eof && (!@readBuff || @readBuff == "")
|
|
264
|
+
return
|
|
265
|
+
end
|
|
266
|
+
end
|
|
267
|
+
end
|
|
268
|
+
def setmode_B
|
|
269
|
+
if block_given?
|
|
270
|
+
tmp = @mode
|
|
271
|
+
begin
|
|
272
|
+
@mode = "B"
|
|
273
|
+
yield
|
|
274
|
+
ensure
|
|
275
|
+
@mode = tmp
|
|
276
|
+
end
|
|
277
|
+
else
|
|
278
|
+
@mode = "B"
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
def read
|
|
282
|
+
ret = ""
|
|
283
|
+
while !@eof
|
|
284
|
+
pre_read
|
|
285
|
+
ret += @readBuff
|
|
286
|
+
@readBuff = ""
|
|
287
|
+
end
|
|
288
|
+
ret
|
|
289
|
+
end
|
|
290
|
+
def unwind s
|
|
291
|
+
@readBuff = s + @readBuff
|
|
292
|
+
end
|
|
293
|
+
def select_write
|
|
294
|
+
self.class.select self, :write
|
|
295
|
+
end
|
|
296
|
+
def select_read
|
|
297
|
+
return if @eof
|
|
298
|
+
p
|
|
299
|
+
self.class.select self, :read
|
|
300
|
+
p
|
|
301
|
+
begin
|
|
302
|
+
p @io
|
|
303
|
+
@readBuff += @io.readpartial 0x3fffffff
|
|
304
|
+
p @readBuff
|
|
305
|
+
rescue EOFError
|
|
306
|
+
p
|
|
307
|
+
@eof = true
|
|
308
|
+
end
|
|
309
|
+
p
|
|
310
|
+
end
|
|
311
|
+
def write arg
|
|
312
|
+
if @mode == :text
|
|
313
|
+
arg = arg.gsub "\n", "\r\n"
|
|
314
|
+
end
|
|
315
|
+
select_write
|
|
316
|
+
p arg
|
|
317
|
+
return @io.write arg
|
|
318
|
+
end
|
|
319
|
+
def writeln arg
|
|
320
|
+
write arg + "\n"
|
|
321
|
+
end
|
|
322
|
+
def pre_read
|
|
323
|
+
loop do
|
|
324
|
+
if @readBuff.size > 0
|
|
325
|
+
break
|
|
326
|
+
end
|
|
327
|
+
@readBuff += @residue
|
|
328
|
+
p
|
|
329
|
+
select_read
|
|
330
|
+
p @readBuff
|
|
331
|
+
if @mode == :text
|
|
332
|
+
@readBuff.gsub! "\r\n", "\n"
|
|
333
|
+
if @mode == :text && @readBuff[-1] == "\r"
|
|
334
|
+
@readBuff.chop!
|
|
335
|
+
@residue = "\r"
|
|
336
|
+
end
|
|
337
|
+
end
|
|
338
|
+
if @readBuff != "" || @eof
|
|
339
|
+
break
|
|
340
|
+
end
|
|
341
|
+
end
|
|
342
|
+
end
|
|
343
|
+
def close
|
|
344
|
+
@io.close if !@io.closed?
|
|
345
|
+
end
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
class OrderedQueue < Array
|
|
349
|
+
def initialize &prc
|
|
350
|
+
@ev = prc
|
|
351
|
+
end
|
|
352
|
+
alias :_insert_at :insert
|
|
353
|
+
def _insert item, bg = 0, ed = size
|
|
354
|
+
if @ev.call(bg) == @ev.call(ed - 1)
|
|
355
|
+
_insert ed - 1, item
|
|
356
|
+
else
|
|
357
|
+
if ed - bg == 1
|
|
358
|
+
_insert_at ed, item
|
|
359
|
+
elsif ed - bg == 2
|
|
360
|
+
_insert_at ed - 1, item
|
|
361
|
+
else
|
|
362
|
+
m = (bg + ed).div 2
|
|
363
|
+
if @ev.call(item) < @ev.call(self[m])
|
|
364
|
+
_insert item, bg, m + 1
|
|
365
|
+
elsif @ev.call(self[m + 1]) <= @ev.call(item)
|
|
366
|
+
_insert item, m + 1, ed
|
|
367
|
+
else
|
|
368
|
+
_insert_at m + 1, item
|
|
369
|
+
end
|
|
370
|
+
end
|
|
371
|
+
end
|
|
372
|
+
end
|
|
373
|
+
def insert item
|
|
374
|
+
if size == 0
|
|
375
|
+
push item
|
|
376
|
+
else
|
|
377
|
+
if @ev.call(self[0]) > @ev.call(item)
|
|
378
|
+
unshift item
|
|
379
|
+
elsif @ev.call(self[-1]) <= @ev.call(item)
|
|
380
|
+
push item
|
|
381
|
+
else
|
|
382
|
+
_insert item
|
|
383
|
+
end
|
|
384
|
+
end
|
|
385
|
+
end
|
|
386
|
+
end
|
|
387
|
+
|
|
388
|
+
def self.fork *modes, &prc # mode : true, execute block firstly
|
|
389
|
+
fi = modes.index :first
|
|
390
|
+
li = modes.index :late
|
|
391
|
+
if !li
|
|
392
|
+
first = true
|
|
393
|
+
elsif !fi
|
|
394
|
+
first = false
|
|
395
|
+
elsif fi > li
|
|
396
|
+
first = true
|
|
397
|
+
else
|
|
398
|
+
first = false
|
|
399
|
+
end
|
|
400
|
+
auto_cleanup = modes.include?(:auto_cleanup) ? :auto_cleanup : nil
|
|
401
|
+
p prc
|
|
402
|
+
fProc = Proc.new do
|
|
403
|
+
begin
|
|
404
|
+
p :yellow
|
|
405
|
+
prc.call
|
|
406
|
+
p :cyan
|
|
407
|
+
rescue SIO::SIOTerminate
|
|
408
|
+
p :red
|
|
409
|
+
rescue Exception => ex
|
|
410
|
+
p :blue
|
|
411
|
+
p ex
|
|
412
|
+
ex.instance_eval {
|
|
413
|
+
::STDERR.write "#{backtrace[0]}:#{ex} (#{self.class})".ln
|
|
414
|
+
backtrace[1..-1].each do |e|
|
|
415
|
+
::STDERR.write(" " + e.ln)
|
|
416
|
+
end
|
|
417
|
+
}
|
|
418
|
+
p
|
|
419
|
+
@aborted = true
|
|
420
|
+
abort
|
|
421
|
+
end
|
|
422
|
+
SIO.sid.delete
|
|
423
|
+
p :blue
|
|
424
|
+
doSelect #never retrun
|
|
425
|
+
end
|
|
426
|
+
ret = SIOProc.new.set_params fProc, first ? :start : :pass, auto_cleanup
|
|
427
|
+
cc = callcc do |cont|
|
|
428
|
+
cont
|
|
429
|
+
end
|
|
430
|
+
p cc
|
|
431
|
+
if cc.is_a? Continuation
|
|
432
|
+
SIO.sid.set_params cc, first ? :pass : :start
|
|
433
|
+
p SIO.sid
|
|
434
|
+
doSelect
|
|
435
|
+
end
|
|
436
|
+
p ret
|
|
437
|
+
ret
|
|
438
|
+
end
|
|
439
|
+
class SIOTerminate < Exception
|
|
440
|
+
end
|
|
441
|
+
def self.select_it *args
|
|
442
|
+
cc = callcc do |cont|
|
|
443
|
+
cont
|
|
444
|
+
end
|
|
445
|
+
p cc
|
|
446
|
+
case cc
|
|
447
|
+
when Continuation
|
|
448
|
+
sid.set_params cc, *args
|
|
449
|
+
doSelect
|
|
450
|
+
when :terminate
|
|
451
|
+
p args
|
|
452
|
+
raise SIOTerminate.new
|
|
453
|
+
p
|
|
454
|
+
end
|
|
455
|
+
cc
|
|
456
|
+
end
|
|
457
|
+
def self.select sio, mode, timeout = nil
|
|
458
|
+
select_it mode, sio, timeout
|
|
459
|
+
end
|
|
460
|
+
def self.pass
|
|
461
|
+
select_it :pass
|
|
462
|
+
end
|
|
463
|
+
def self.sleep t = :stop
|
|
464
|
+
p :purple
|
|
465
|
+
select_it t
|
|
466
|
+
p :purple
|
|
467
|
+
end
|
|
468
|
+
def self.stopBy token, timeout = :stop
|
|
469
|
+
res = select_it token, timeout
|
|
470
|
+
if res == :start
|
|
471
|
+
:timeout
|
|
472
|
+
else
|
|
473
|
+
token
|
|
474
|
+
end
|
|
475
|
+
end
|
|
476
|
+
def self.awakeBy token
|
|
477
|
+
SIOProc::List.each do |prc|
|
|
478
|
+
if prc.token == token
|
|
479
|
+
prc.set_params :start
|
|
480
|
+
end
|
|
481
|
+
end
|
|
482
|
+
select_it :start
|
|
483
|
+
end
|
|
484
|
+
def self.timer t
|
|
485
|
+
loop do
|
|
486
|
+
yield
|
|
487
|
+
sleep t
|
|
488
|
+
end
|
|
489
|
+
end
|
|
490
|
+
def self.doSelect
|
|
491
|
+
wios = []
|
|
492
|
+
rios = []
|
|
493
|
+
active_procs = []
|
|
494
|
+
hasTimer = false
|
|
495
|
+
SIOProc::List.each do |prc|
|
|
496
|
+
if prc.timeout
|
|
497
|
+
hasTimer = true
|
|
498
|
+
break
|
|
499
|
+
end
|
|
500
|
+
end
|
|
501
|
+
now = Time.now if hasTimer
|
|
502
|
+
tmout, passProc = nil
|
|
503
|
+
tmoutList = []
|
|
504
|
+
wio2SIOPrc = Hash.new{|h, k| h[k] = []}
|
|
505
|
+
rio2SIOPrc = Hash.new{|h, k| h[k] = []}
|
|
506
|
+
SIOProc::List.each do |prc|
|
|
507
|
+
p prc.selected?, prc.mode, prc.preceeded
|
|
508
|
+
next if prc.preceeded
|
|
509
|
+
case prc.selected? || prc.mode
|
|
510
|
+
when :read, :write
|
|
511
|
+
if prc.mode == :read
|
|
512
|
+
rio2SIOPrc[prc.io].push prc
|
|
513
|
+
rios.push prc.io
|
|
514
|
+
else # :write
|
|
515
|
+
wio2SIOPrc[prc.io].push prc
|
|
516
|
+
wios.push prc.io
|
|
517
|
+
end
|
|
518
|
+
if prc.timeout
|
|
519
|
+
if !tmout || (tmout != 0 and tmout > prc.timeout - now and tmoutList.clear)
|
|
520
|
+
tmout = prc.timeout - now
|
|
521
|
+
tmout = 0 if tmout < 0
|
|
522
|
+
end
|
|
523
|
+
end
|
|
524
|
+
when :timer
|
|
525
|
+
if !tmout
|
|
526
|
+
tmout = prc.timeout - now
|
|
527
|
+
tmout = 0 if tmout < 0
|
|
528
|
+
tmoutList.push prc
|
|
529
|
+
elsif tmout == 0 && prc.timeout - now <= 0
|
|
530
|
+
tmoutList.push prc
|
|
531
|
+
elsif tmout == prc.timeout - now
|
|
532
|
+
tmoutList.push prc
|
|
533
|
+
elsif tmout > prc.timeout - now
|
|
534
|
+
tmout = prc.timeout - now
|
|
535
|
+
tmout = 0 if tmout < 0
|
|
536
|
+
tmoutList.clear
|
|
537
|
+
tmoutList.push prc
|
|
538
|
+
end
|
|
539
|
+
when :stop
|
|
540
|
+
# do nothing
|
|
541
|
+
when :terminate, :start, true
|
|
542
|
+
if !tmout
|
|
543
|
+
tmout = 0
|
|
544
|
+
tmoutList.push prc
|
|
545
|
+
elsif tmout == 0
|
|
546
|
+
tmoutList.push prc
|
|
547
|
+
else
|
|
548
|
+
tmout = 0
|
|
549
|
+
tmoutList.clear
|
|
550
|
+
tmoutList.push prc
|
|
551
|
+
end
|
|
552
|
+
when :pass
|
|
553
|
+
passProc = prc
|
|
554
|
+
prc.set_params :start
|
|
555
|
+
else # token
|
|
556
|
+
# do nothing
|
|
557
|
+
end
|
|
558
|
+
end
|
|
559
|
+
p tmout
|
|
560
|
+
p [rios, wios, tmoutList]
|
|
561
|
+
if rios.size + wios.size + tmoutList.size == 0
|
|
562
|
+
p
|
|
563
|
+
if passProc
|
|
564
|
+
p passProc
|
|
565
|
+
tmoutList.push passProc
|
|
566
|
+
else
|
|
567
|
+
p
|
|
568
|
+
raise Exception.new("no selectable SIOProc")
|
|
569
|
+
end
|
|
570
|
+
end
|
|
571
|
+
p
|
|
572
|
+
selectedList, srios, swios, seios = nil
|
|
573
|
+
if ((!tmout && rios.size + wios.size > 0) || (tmout && tmout != 0))
|
|
574
|
+
p
|
|
575
|
+
begin
|
|
576
|
+
p tmout, wios, rios
|
|
577
|
+
srios, swios, seios = IO.select rios, wios, rios + wios, tmout
|
|
578
|
+
rescue Errno::EINTR
|
|
579
|
+
retry
|
|
580
|
+
end
|
|
581
|
+
now = nil
|
|
582
|
+
timeouted = (!srios || srios.size == 0) && (!swios || swios.size == 0)
|
|
583
|
+
[[rios, srios, rio2SIOPrc], [wios, swios, wio2SIOPrc]].each do |ios, sios, io2SIOPrc|
|
|
584
|
+
ios.each do |io|
|
|
585
|
+
e = io2SIOPrc[io].shuffle[0]
|
|
586
|
+
if (sios && sios.include?(io)) || (e.timeout && e.timeout < (now ||= Time.now))
|
|
587
|
+
e.set_selected
|
|
588
|
+
(selectedList ||= []).push e
|
|
589
|
+
end
|
|
590
|
+
end
|
|
591
|
+
end
|
|
592
|
+
else #tmout = 0
|
|
593
|
+
p
|
|
594
|
+
timeouted = true
|
|
595
|
+
end
|
|
596
|
+
p srios
|
|
597
|
+
p swios
|
|
598
|
+
p seios
|
|
599
|
+
p selectedList
|
|
600
|
+
p tmoutList
|
|
601
|
+
if timeouted
|
|
602
|
+
(selectedList ||= []).push *tmoutList
|
|
603
|
+
end
|
|
604
|
+
current_proc = selectedList.shuffle[0]
|
|
605
|
+
current_proc.reset_selected if current_proc.selected?
|
|
606
|
+
p current_proc
|
|
607
|
+
current_proc.continue
|
|
608
|
+
end
|
|
609
|
+
class SIOProc
|
|
610
|
+
attr_reader :mode, :sio, :timeout, :token, :preceeded
|
|
611
|
+
List = []
|
|
612
|
+
def initialize
|
|
613
|
+
List.push self
|
|
614
|
+
@mutexStack = []
|
|
615
|
+
@lockStat = []
|
|
616
|
+
@mutexList = Hash.new{|h, k| h[k] = 0}
|
|
617
|
+
@preceeded = false
|
|
618
|
+
end
|
|
619
|
+
def delete
|
|
620
|
+
List.delete self
|
|
621
|
+
end
|
|
622
|
+
def auto_cleanup?
|
|
623
|
+
@auto_cleanup
|
|
624
|
+
end
|
|
625
|
+
def io
|
|
626
|
+
if sio.is_a? SIO
|
|
627
|
+
sio.io
|
|
628
|
+
else
|
|
629
|
+
sio
|
|
630
|
+
end
|
|
631
|
+
end
|
|
632
|
+
def set_params *args
|
|
633
|
+
@mode, @timeout, @sio, @token, @selected = nil
|
|
634
|
+
args.each do |e|
|
|
635
|
+
case e
|
|
636
|
+
when Continuation, Proc
|
|
637
|
+
@cont = e
|
|
638
|
+
when :auto_cleanup
|
|
639
|
+
p
|
|
640
|
+
@auto_cleanup = true
|
|
641
|
+
when Symbol
|
|
642
|
+
@mode = e
|
|
643
|
+
when Time
|
|
644
|
+
@timeout = e
|
|
645
|
+
when Numeric
|
|
646
|
+
@timeout = Time.now + e
|
|
647
|
+
when SIO
|
|
648
|
+
@sio = e
|
|
649
|
+
when nil
|
|
650
|
+
else
|
|
651
|
+
@token = e
|
|
652
|
+
end
|
|
653
|
+
end
|
|
654
|
+
@timeout and @mode ||= :timer
|
|
655
|
+
self
|
|
656
|
+
end
|
|
657
|
+
class SIOTerminate < Exception
|
|
658
|
+
end
|
|
659
|
+
def set_selected
|
|
660
|
+
@selected = true
|
|
661
|
+
end
|
|
662
|
+
def reset_selected
|
|
663
|
+
@selected = false
|
|
664
|
+
end
|
|
665
|
+
def selected?
|
|
666
|
+
return @selected
|
|
667
|
+
end
|
|
668
|
+
def awake_at t = 0
|
|
669
|
+
set_params t
|
|
670
|
+
end
|
|
671
|
+
def continue arg = nil
|
|
672
|
+
@mutexStack.each do |e|
|
|
673
|
+
if e.has_semi_lock_sid self
|
|
674
|
+
e.lock self
|
|
675
|
+
end
|
|
676
|
+
end
|
|
677
|
+
m = arg || @mode
|
|
678
|
+
cc = @cont
|
|
679
|
+
@cont, @mode, @timeout, @sio, @token = nil
|
|
680
|
+
SIO.set_sid self
|
|
681
|
+
cc.call m
|
|
682
|
+
end
|
|
683
|
+
def terminate
|
|
684
|
+
if SIO.sid == self
|
|
685
|
+
raise SIOTerminate.new
|
|
686
|
+
end
|
|
687
|
+
set_params :terminate
|
|
688
|
+
SIO.select_it :pass
|
|
689
|
+
end
|
|
690
|
+
def awake
|
|
691
|
+
set_params :start
|
|
692
|
+
SIO.select_it :pass
|
|
693
|
+
end
|
|
694
|
+
def set_awake
|
|
695
|
+
set_params :start
|
|
696
|
+
end
|
|
697
|
+
def set_preceeded
|
|
698
|
+
@preceeded = true
|
|
699
|
+
end
|
|
700
|
+
def reset_preceeded
|
|
701
|
+
@preceeded = false
|
|
702
|
+
end
|
|
703
|
+
def mutexSyncLock
|
|
704
|
+
mutex = @mutexStack[-1]
|
|
705
|
+
if !@lockStat[-1]
|
|
706
|
+
@lockStat[-1] = true
|
|
707
|
+
mutex.lock self
|
|
708
|
+
end
|
|
709
|
+
end
|
|
710
|
+
def mutexSyncUnlock
|
|
711
|
+
mutex = @mutexStack[-1]
|
|
712
|
+
mutex.unlock self
|
|
713
|
+
end
|
|
714
|
+
def mutexSync mutex, mode
|
|
715
|
+
res = nil
|
|
716
|
+
begin
|
|
717
|
+
@mutexList[mutex] += 1
|
|
718
|
+
@mutexStack.push mutex
|
|
719
|
+
@lockStat.push false
|
|
720
|
+
case mode
|
|
721
|
+
when :semi
|
|
722
|
+
mutex.set_semi_lock_sid self
|
|
723
|
+
else
|
|
724
|
+
mutexSyncLock
|
|
725
|
+
end
|
|
726
|
+
begin
|
|
727
|
+
res = yield
|
|
728
|
+
ensure
|
|
729
|
+
mutexSyncUnlock
|
|
730
|
+
end
|
|
731
|
+
ensure
|
|
732
|
+
tmp = (@mutexList[mutex] -= 1)
|
|
733
|
+
if tmp == 0
|
|
734
|
+
@mutexList.delete mutex
|
|
735
|
+
end
|
|
736
|
+
@mutexStack.pop
|
|
737
|
+
@lockStat.pop
|
|
738
|
+
res
|
|
739
|
+
end
|
|
740
|
+
end
|
|
741
|
+
end
|
|
742
|
+
class Mutex
|
|
743
|
+
def initialize
|
|
744
|
+
@stopped = {}
|
|
745
|
+
@semi_lock_sids = Hash.new{|h, k| h[k] = 0}
|
|
746
|
+
@waiting_sids = Hash.new
|
|
747
|
+
end
|
|
748
|
+
def lock sid
|
|
749
|
+
while @sid && @sid != sid
|
|
750
|
+
@waiting_sids[sid] = true
|
|
751
|
+
SIO.sleep
|
|
752
|
+
end
|
|
753
|
+
@sid = sid
|
|
754
|
+
@semi_lock_sids.keys.each do |e|
|
|
755
|
+
if e != sid
|
|
756
|
+
e.set_preceeded
|
|
757
|
+
end
|
|
758
|
+
end
|
|
759
|
+
@sid.reset_preceeded
|
|
760
|
+
end
|
|
761
|
+
def unlock sid
|
|
762
|
+
if @sid == sid
|
|
763
|
+
@semi_lock_sids.keys.each do |e|
|
|
764
|
+
if e != self
|
|
765
|
+
e.reset_preceeded
|
|
766
|
+
end
|
|
767
|
+
end
|
|
768
|
+
@waiting_sids.each do |e|
|
|
769
|
+
e.set_awake
|
|
770
|
+
end
|
|
771
|
+
@sid = nil
|
|
772
|
+
end
|
|
773
|
+
end
|
|
774
|
+
def set_semi_lock_sid sid
|
|
775
|
+
@semi_lock_sids[sid] += 1
|
|
776
|
+
end
|
|
777
|
+
def reset_semi_lock_sid sid
|
|
778
|
+
if @semi_lock_sids.key? sid
|
|
779
|
+
tmp = (@semi_lock_sids[sid] -= 1)
|
|
780
|
+
if tmp <= 0
|
|
781
|
+
@semi_lock_sids.delete sid
|
|
782
|
+
end
|
|
783
|
+
end
|
|
784
|
+
end
|
|
785
|
+
def has_semi_lock_sid sid
|
|
786
|
+
@semi_lock_sids.key? sid
|
|
787
|
+
end
|
|
788
|
+
def synchronize mode = :normal, &prc
|
|
789
|
+
SIO.sid.mutexSync self, mode, &prc
|
|
790
|
+
end
|
|
791
|
+
end
|
|
792
|
+
STDIN = SIO.new ::STDIN
|
|
793
|
+
STDOUT = SIO.new ::STDOUT
|
|
794
|
+
STDERR = SIO.new ::STDOUT
|
|
795
|
+
def tmode= m
|
|
796
|
+
@mode = m
|
|
797
|
+
end
|
|
798
|
+
def tmode
|
|
799
|
+
@mode
|
|
800
|
+
end
|
|
801
|
+
def self.set_sid arg
|
|
802
|
+
@sid = arg
|
|
803
|
+
end
|
|
804
|
+
def self.sid
|
|
805
|
+
@sid
|
|
806
|
+
end
|
|
807
|
+
self.set_sid SIOProc.new
|
|
808
|
+
|
|
809
|
+
at_exit do
|
|
810
|
+
p :cyan, $!
|
|
811
|
+
if $! && !$!.is_a?(SystemExit)
|
|
812
|
+
$!.instance_eval {
|
|
813
|
+
STDERR.write "#{backtrace[0]}:#{$!} (#{self.class})".ln
|
|
814
|
+
backtrace[1..-1].each do |e|
|
|
815
|
+
STDERR.write " " + e.ln
|
|
816
|
+
end
|
|
817
|
+
}
|
|
818
|
+
@aborted = true
|
|
819
|
+
abort
|
|
820
|
+
end
|
|
821
|
+
p SIOProc::List.size
|
|
822
|
+
toTerm = []
|
|
823
|
+
SIOProc::List.each do |prc|
|
|
824
|
+
if prc.auto_cleanup?
|
|
825
|
+
toTerm.push prc
|
|
826
|
+
end
|
|
827
|
+
end
|
|
828
|
+
p toTerm
|
|
829
|
+
p SIOProc::List.size
|
|
830
|
+
toTerm.each &:terminate
|
|
831
|
+
p SIOProc::List.size
|
|
832
|
+
if !@aborted && SIOProc::List.size > 1
|
|
833
|
+
p SIOProc::List
|
|
834
|
+
raise Exception.new("#{SIOProc::List.size - 1} SIO Fork procedure(s) not cleand")
|
|
835
|
+
end
|
|
836
|
+
p
|
|
837
|
+
end
|
|
838
|
+
end
|
|
839
|
+
|
|
840
|
+
|
|
841
|
+
class String
|
|
842
|
+
def strip_indent
|
|
843
|
+
mn = 1000000
|
|
844
|
+
last = nil
|
|
845
|
+
each_line do |ln|
|
|
846
|
+
break if ln[-1] != "\n" and last = ln
|
|
847
|
+
ln.chomp =~ /^\s*/
|
|
848
|
+
next if $'.size == 0
|
|
849
|
+
if $&.size < mn
|
|
850
|
+
mn = $&.size
|
|
851
|
+
end
|
|
852
|
+
end
|
|
853
|
+
res = ""
|
|
854
|
+
each_line do |ln|
|
|
855
|
+
break if ln[-1] != "\n"
|
|
856
|
+
res += ln[mn..-1] if ln[mn..-1]
|
|
857
|
+
end
|
|
858
|
+
if last
|
|
859
|
+
if last.size <= mn
|
|
860
|
+
res += last.lstrip
|
|
861
|
+
else
|
|
862
|
+
res += last[mn..-1]
|
|
863
|
+
end
|
|
864
|
+
end
|
|
865
|
+
replace(res)
|
|
866
|
+
self
|
|
867
|
+
end
|
|
868
|
+
end
|
|
869
|
+
|
|
870
|
+
|
|
871
|
+
class SIOResolver
|
|
872
|
+
Sock = SIO.new UDPSocket.open, :read
|
|
873
|
+
begin
|
|
874
|
+
Sock.io.bind("0.0.0.0", rand(1024..65535))
|
|
875
|
+
rescue => Errno::EADDRINUSE
|
|
876
|
+
retry
|
|
877
|
+
end
|
|
878
|
+
resolvers = []
|
|
879
|
+
"/etc/resolv.conf".read_each_line do |ln|
|
|
880
|
+
if ln.strip =~ /nameserver\s*/ && $' =~ IPv4Regexp
|
|
881
|
+
resolvers.push $&
|
|
882
|
+
end
|
|
883
|
+
end
|
|
884
|
+
Resolvers = resolvers
|
|
885
|
+
MaxRetrial = 5
|
|
886
|
+
EachResolvTimeout = 0.2
|
|
887
|
+
ResolvTimeout = 1.01
|
|
888
|
+
|
|
889
|
+
def self.check_init
|
|
890
|
+
if !@initialized
|
|
891
|
+
@initialized = true
|
|
892
|
+
SIO.fork :auto_cleanup do
|
|
893
|
+
p
|
|
894
|
+
loop do
|
|
895
|
+
p
|
|
896
|
+
SIO.select Sock, :read
|
|
897
|
+
p
|
|
898
|
+
pkt = Sock.io.recvfrom(1024)
|
|
899
|
+
parsed = Net::DNS::Packet::parse(pkt)
|
|
900
|
+
name, ip, ttl = nil
|
|
901
|
+
parsed.question.each do |rr|
|
|
902
|
+
p rr.qType.to_s
|
|
903
|
+
p rr.qType.to_s.class
|
|
904
|
+
if rr.qType.to_s == "A"
|
|
905
|
+
name = rr.qName
|
|
906
|
+
if name[-1..-1] == "."
|
|
907
|
+
name.chop!
|
|
908
|
+
end
|
|
909
|
+
break
|
|
910
|
+
end
|
|
911
|
+
end
|
|
912
|
+
parsed.answer.each do |rr|
|
|
913
|
+
if rr.type == "A"
|
|
914
|
+
ip, ttl = rr.address.to_s, rr.ttl
|
|
915
|
+
break
|
|
916
|
+
end
|
|
917
|
+
end
|
|
918
|
+
if ip and name
|
|
919
|
+
p [name, ip, ttl]
|
|
920
|
+
Status[name].setResult ip, ttl
|
|
921
|
+
p
|
|
922
|
+
SIO.awakeBy [self, name]
|
|
923
|
+
p
|
|
924
|
+
end
|
|
925
|
+
end
|
|
926
|
+
end
|
|
927
|
+
end
|
|
928
|
+
end
|
|
929
|
+
|
|
930
|
+
p
|
|
931
|
+
class Status
|
|
932
|
+
attr_reader :expiry, :ip
|
|
933
|
+
def self.[] name
|
|
934
|
+
@list ||= Hash.new{|h, k| h[k] = Status.new(k)}
|
|
935
|
+
@list[name]
|
|
936
|
+
end
|
|
937
|
+
def initialize name
|
|
938
|
+
@name = name
|
|
939
|
+
@expiry = Time.at(0)
|
|
940
|
+
end
|
|
941
|
+
def resolve
|
|
942
|
+
p
|
|
943
|
+
if @resolving
|
|
944
|
+
p
|
|
945
|
+
@retrialLeft = MaxRetrial
|
|
946
|
+
return
|
|
947
|
+
end
|
|
948
|
+
p
|
|
949
|
+
@resolving = true
|
|
950
|
+
p
|
|
951
|
+
@retrialLeft = MaxRetrial
|
|
952
|
+
p
|
|
953
|
+
SIO.fork do
|
|
954
|
+
p
|
|
955
|
+
begin
|
|
956
|
+
p
|
|
957
|
+
pkt = Net::DNS::Packet.new @name
|
|
958
|
+
p
|
|
959
|
+
begin
|
|
960
|
+
p
|
|
961
|
+
@retrialLeft -= 1
|
|
962
|
+
p
|
|
963
|
+
Sock.io.send(pkt.data, 0, Resolvers[rand(0...Resolvers.size)], 53)
|
|
964
|
+
p
|
|
965
|
+
if !SIO.stopBy [self, @name], EachResolvTimeout
|
|
966
|
+
p
|
|
967
|
+
redo if @retrialLeft > 0
|
|
968
|
+
end
|
|
969
|
+
p
|
|
970
|
+
end
|
|
971
|
+
ensure
|
|
972
|
+
@resolving = false
|
|
973
|
+
end
|
|
974
|
+
end
|
|
975
|
+
p
|
|
976
|
+
end
|
|
977
|
+
def setResult ip, ttl
|
|
978
|
+
@ip = ip
|
|
979
|
+
@expiry = Time.now + ttl
|
|
980
|
+
end
|
|
981
|
+
end
|
|
982
|
+
|
|
983
|
+
def self.resolv name
|
|
984
|
+
check_init
|
|
985
|
+
stat = Status[name]
|
|
986
|
+
if stat.expiry > Time.now
|
|
987
|
+
return stat.ip
|
|
988
|
+
end
|
|
989
|
+
p
|
|
990
|
+
stat.resolve
|
|
991
|
+
p
|
|
992
|
+
SIO.stopBy [self, name], ResolvTimeout
|
|
993
|
+
p stat.ip
|
|
994
|
+
return stat.ip
|
|
995
|
+
end
|
|
996
|
+
|
|
997
|
+
|
|
998
|
+
end
|
|
999
|
+
|
|
1000
|
+
|
|
1001
|
+
|