YkLib 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (125) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +6 -0
  5. data/CODE_OF_CONDUCT.md +74 -0
  6. data/Gemfile +7 -0
  7. data/Gemfile.lock +34 -0
  8. data/LICENSE.txt +21 -0
  9. data/README.md +44 -0
  10. data/Rakefile +6 -0
  11. data/YkLib.gemspec +29 -0
  12. data/bin/console +14 -0
  13. data/bin/setup +8 -0
  14. data/lib/YkLib/Yk/__advance__.rb +151 -0
  15. data/lib/YkLib/Yk/__defun__.rb +44 -0
  16. data/lib/YkLib/Yk/__hook__.rb +244 -0
  17. data/lib/YkLib/Yk/__minmax__.rb +123 -0
  18. data/lib/YkLib/Yk/__stdlog.rb +329 -0
  19. data/lib/YkLib/Yk/adhocLiterals/email.rb +119 -0
  20. data/lib/YkLib/Yk/adhocLiterals/path.rb +402 -0
  21. data/lib/YkLib/Yk/adhocLiterals/tag.rb +19 -0
  22. data/lib/YkLib/Yk/adhocLiterals/url.rb +36 -0
  23. data/lib/YkLib/Yk/adhocLiterals.rb +199 -0
  24. data/lib/YkLib/Yk/auto_escseq.rb +5 -0
  25. data/lib/YkLib/Yk/auto_pstore.rb +179 -0
  26. data/lib/YkLib/Yk/bsearch.rb +120 -0
  27. data/lib/YkLib/Yk/clambda.rb +309 -0
  28. data/lib/YkLib/Yk/confLine.rb +423 -0
  29. data/lib/YkLib/Yk/create_tty_width_available.rb +24 -0
  30. data/lib/YkLib/Yk/crypt.rb +26 -0
  31. data/lib/YkLib/Yk/debug2 +1 -0
  32. data/lib/YkLib/Yk/debug2.rb +473 -0
  33. data/lib/YkLib/Yk/debugout.rb +139 -0
  34. data/lib/YkLib/Yk/email_tz.rb +533 -0
  35. data/lib/YkLib/Yk/enum_expect.rb +170 -0
  36. data/lib/YkLib/Yk/errlog.rb +5 -0
  37. data/lib/YkLib/Yk/escseq.rb +59 -0
  38. data/lib/YkLib/Yk/eval_alt.rb +281 -0
  39. data/lib/YkLib/Yk/expector.rb +93 -0
  40. data/lib/YkLib/Yk/fetch.rb +556 -0
  41. data/lib/YkLib/Yk/fetch_old.rb +290 -0
  42. data/lib/YkLib/Yk/fib.rb +158 -0
  43. data/lib/YkLib/Yk/file_aux.rb +843 -0
  44. data/lib/YkLib/Yk/file_aux2.rb +919 -0
  45. data/lib/YkLib/Yk/file_aux_old.rb +160 -0
  46. data/lib/YkLib/Yk/filemod.rb +19 -0
  47. data/lib/YkLib/Yk/force_escseq.rb +3 -0
  48. data/lib/YkLib/Yk/generator__.rb +144 -0
  49. data/lib/YkLib/Yk/generator__.rb.org +139 -0
  50. data/lib/YkLib/Yk/indenter/argless_case.rb +46 -0
  51. data/lib/YkLib/Yk/indenter/each_token.rb +671 -0
  52. data/lib/YkLib/Yk/indenter/free_case.rb +313 -0
  53. data/lib/YkLib/Yk/indenter/if_less.rb +53 -0
  54. data/lib/YkLib/Yk/indenter/independent_ensure.rb +23 -0
  55. data/lib/YkLib/Yk/indenter/independent_rescue.rb +23 -0
  56. data/lib/YkLib/Yk/indenter/operand_circumflex.rb +0 -0
  57. data/lib/YkLib/Yk/indenter/operand_period.rb +16 -0
  58. data/lib/YkLib/Yk/indenter/parenless_and.rb +37 -0
  59. data/lib/YkLib/Yk/indenter/post_test.rb +48 -0
  60. data/lib/YkLib/Yk/indenter/token.rb +1525 -0
  61. data/lib/YkLib/Yk/indenter.rb +1382 -0
  62. data/lib/YkLib/Yk/inot.rb +265 -0
  63. data/lib/YkLib/Yk/intf.rb +815 -0
  64. data/lib/YkLib/Yk/io_aux.rb +1332 -0
  65. data/lib/YkLib/Yk/ioctl.rb +60 -0
  66. data/lib/YkLib/Yk/ipcc.rb +87 -0
  67. data/lib/YkLib/Yk/ipcountry.rb +207 -0
  68. data/lib/YkLib/Yk/ipv4adr.rb +318 -0
  69. data/lib/YkLib/Yk/localmail.rb +276 -0
  70. data/lib/YkLib/Yk/method_chain.rb +359 -0
  71. data/lib/YkLib/Yk/misc_tz.rb +1716 -0
  72. data/lib/YkLib/Yk/missing_method.rb +50 -0
  73. data/lib/YkLib/Yk/mojiConv.rb +257 -0
  74. data/lib/YkLib/Yk/nostdlog.rb +4 -0
  75. data/lib/YkLib/Yk/on_marshal.rb +20 -0
  76. data/lib/YkLib/Yk/overrider.rb +47 -0
  77. data/lib/YkLib/Yk/path.rb +293 -0
  78. data/lib/YkLib/Yk/path_aux.rb +883 -0
  79. data/lib/YkLib/Yk/path_aux_alt.rb +0 -0
  80. data/lib/YkLib/Yk/path_rep.rb +1267 -0
  81. data/lib/YkLib/Yk/pg_setup.rb +917 -0
  82. data/lib/YkLib/Yk/procinfo.rb +314 -0
  83. data/lib/YkLib/Yk/proclist.rb +492 -0
  84. data/lib/YkLib/Yk/property.rb +863 -0
  85. data/lib/YkLib/Yk/ranger.rb +606 -0
  86. data/lib/YkLib/Yk/resolv_tz.rb +88 -0
  87. data/lib/YkLib/Yk/rlprompt.rb +73 -0
  88. data/lib/YkLib/Yk/rootexec.rb +48 -0
  89. data/lib/YkLib/Yk/rpm-packageproxy.rb +784 -0
  90. data/lib/YkLib/Yk/rpm-packageproxy2.rb +1430 -0
  91. data/lib/YkLib/Yk/rwhen.rb +21 -0
  92. data/lib/YkLib/Yk/selector.rb +124 -0
  93. data/lib/YkLib/Yk/set.rb +170 -0
  94. data/lib/YkLib/Yk/shellquote.rb +300 -0
  95. data/lib/YkLib/Yk/sio.rb +1001 -0
  96. data/lib/YkLib/Yk/sio0.rb +835 -0
  97. data/lib/YkLib/Yk/sio_aux.rb +1524 -0
  98. data/lib/YkLib/Yk/sio_inot.rb +86 -0
  99. data/lib/YkLib/Yk/sock_aux.rb +42 -0
  100. data/lib/YkLib/Yk/spipe.rb +843 -0
  101. data/lib/YkLib/Yk/sql_table.rb +565 -0
  102. data/lib/YkLib/Yk/stdlog.rb +4 -0
  103. data/lib/YkLib/Yk/syscommand.rb +173 -0
  104. data/lib/YkLib/Yk/sysinit.rb +75 -0
  105. data/lib/YkLib/Yk/ttyFontWidth.rb +46113 -0
  106. data/lib/YkLib/Yk/tty_char.dump +0 -0
  107. data/lib/YkLib/Yk/tty_char.rb +47 -0
  108. data/lib/YkLib/Yk/tty_char_create.rb +437031 -0
  109. data/lib/YkLib/Yk/tty_char_static.rb +437016 -0
  110. data/lib/YkLib/Yk/tty_rewrite.rb +142 -0
  111. data/lib/YkLib/Yk/tty_str.rb +461 -0
  112. data/lib/YkLib/Yk/tty_width.dat.rb +114 -0
  113. data/lib/YkLib/Yk/tty_width.rb +180 -0
  114. data/lib/YkLib/Yk/tty_width_available +569 -0
  115. data/lib/YkLib/Yk/tty_width_list +0 -0
  116. data/lib/YkLib/Yk/tty_width_list.linux +280 -0
  117. data/lib/YkLib/Yk/tty_width_list.windows +324 -0
  118. data/lib/YkLib/Yk/tz_tty +0 -0
  119. data/lib/YkLib/Yk/tz_tty.rb +0 -0
  120. data/lib/YkLib/Yk/uprepos.rb +94 -0
  121. data/lib/YkLib/Yk/userinfo.rb +91 -0
  122. data/lib/YkLib/Yk/with.rb +109 -0
  123. data/lib/YkLib/version.rb +3 -0
  124. data/lib/YkLib.rb +6 -0
  125. metadata +170 -0
@@ -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
+