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,1716 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ #require 'continuation'
4
+ require 'binding_of_caller'
5
+
6
+
7
+ def die msg = nil
8
+ if msg
9
+ STDERR.write msg.chomp.ln
10
+ end
11
+ exit 1
12
+ end
13
+
14
+ def btrace
15
+ ret = nil
16
+ begin
17
+ raise 'dummy'
18
+ rescue
19
+ ret = $!.backtrace
20
+ end
21
+ ret.shift
22
+ ret.shift
23
+ ret.each do |e|
24
+ e.sub! /(.*):(\d+).*/ do
25
+ $1.basename + ":" + $2
26
+ end
27
+ end
28
+ lst = nil
29
+ ret2 = []
30
+ ret.each do |e|
31
+ e =~ /:(\d+)/
32
+ if $` != lst
33
+ lst = $`
34
+ ret2.push e
35
+ else
36
+ ret2[-1] += "," + $1
37
+ end
38
+ end
39
+ ret2
40
+ end
41
+
42
+
43
+ TopLevelMethod = Object.new
44
+ class << TopLevelMethod
45
+ instance_methods.each { |m|
46
+ if !["object_id", "__send__", "__id__"].include? m.to_s
47
+ undef_method m
48
+ end
49
+ }
50
+ def method_missing (name, *args, **opts, &bl)
51
+ p.bgRed TopLevelMethod
52
+ TOPLEVEL_BINDING.eval("self").__send__(name, *args, **opts, &bl)
53
+ end
54
+ def respond_to? name, include_all = false
55
+ TOPLEVEL_BINDING.eval("self").respond_to? name, true
56
+ end
57
+ end
58
+
59
+
60
+ def parse_caller(at)
61
+ if /^(.+?):(\d+)(?::in `(.*)')?/ =~ at
62
+ file = $1
63
+ line = $2.to_i
64
+ method = $3
65
+ [file, line, method]
66
+ end
67
+ end
68
+
69
+
70
+
71
+ def caller_binding
72
+ return binding.of_caller(2)
73
+ cc = nil # must be present to work within lambda
74
+ ## cpos = parse_caller(caller.first)
75
+ count = 0 # counter of returns
76
+ ## traceArr = []
77
+
78
+ ret = callcc do |cont|
79
+ cc = cont
80
+ nil
81
+ end
82
+
83
+ if !ret
84
+ set_trace_func lambda { |event, file, lineno, id, binding, klass|
85
+ ## traceArr.push [event, file, lineno, count, cc, id, klass, eval("self.class", binding)]
86
+ # First return gets to the caller of this method
87
+ # (which already know its own binding).
88
+ # Second return gets to the caller of the caller.
89
+ # That's we want!
90
+ if count == 2
91
+ set_trace_func nil
92
+ # Will return the binding to the callcc below
93
+ if cc == nil
94
+ ## STDERR.write [cpos, traceArr].inspect.ln
95
+ ## STDERR.flush
96
+ Process.kill :TERM, Process.pid
97
+ sleep 1000
98
+ end
99
+ cc.call binding
100
+ elsif event == "return"
101
+ count += 1
102
+ end
103
+ }
104
+ end
105
+ # First time it'll set the cc and return nil to the caller.
106
+ # So it's important to the caller to return again
107
+ # if it gets nil, then we get the second return.
108
+ # Second time it'll return the binding.
109
+ ## traceArr.push [cc, ret]
110
+ return ret
111
+ end
112
+
113
+
114
+ def assign_it label, value
115
+ return unless bnd = caller_binding
116
+ old_id = bnd.eval(label.to_s).__id__
117
+ new_id = value.__id__
118
+ bnd.eval("#{label.to_s} = ObjectSpace._id2ref(#{new_id})")
119
+ begin
120
+ yield ObjectSpace._id2ref(old_id)
121
+ ensure
122
+ bnd.eval("#{label.to_s} = ObjectSpace._id2ref(#{old_id})")
123
+ end
124
+ end
125
+
126
+
127
+ class Object
128
+ def significant?
129
+ true
130
+ end
131
+ end
132
+
133
+ class NQObject
134
+ instance_methods.each { |m|
135
+ if !["__id__", "__send__", "object_id"].include? m.to_s
136
+ undef_method m
137
+ end
138
+ }
139
+ def method_missing (name, *args, &bl)
140
+ self
141
+ end
142
+ def initialize
143
+ end
144
+ def nil?
145
+ true
146
+ end
147
+ def __it
148
+ return nil
149
+ end
150
+ def respond_to? m
151
+ m == :__isNQObject__?
152
+ end
153
+ def coerce a
154
+ [self, a]
155
+ end
156
+ Obj = NQObject.new
157
+ end
158
+
159
+
160
+ class Object
161
+ if !method_defined? :then
162
+ def then &prc
163
+ if !nil?
164
+ prc.call self
165
+ end
166
+ end
167
+ end
168
+ def _? &prc
169
+ if self == TopLevelSelf
170
+ return unless bnd = caller_binding
171
+ end
172
+ if !prc
173
+ QObject.new bnd || self
174
+ else
175
+ if res = prc.call(self)
176
+ if res.is_a?(Label)
177
+ if method(res).call
178
+ self
179
+ else
180
+ nil
181
+ end
182
+ else
183
+ self
184
+ end
185
+ else
186
+ nil
187
+ end
188
+ end
189
+ end
190
+ def _! &prc
191
+ if self == TopLevelSelf
192
+ return unless bnd = caller_binding
193
+ end
194
+ if !prc
195
+ QObject.new bnd || self, false
196
+ else
197
+ if !prc.call(self)
198
+ self
199
+ else
200
+ nil
201
+ end
202
+ end
203
+ end
204
+ def __not?
205
+ QObject.new self, false
206
+ end
207
+ def __and?
208
+ self
209
+ end
210
+ def __it &bl
211
+ if bl
212
+ bl.call self
213
+ else
214
+ self
215
+ end
216
+ end
217
+ if !method_defined? :tap
218
+ def tap
219
+ yield self
220
+ self
221
+ end
222
+ end
223
+ end
224
+
225
+ def __topl____
226
+ self
227
+ end
228
+ TopLevelSelf = __topl____
229
+
230
+
231
+ def nil._?
232
+ return NQObject.new
233
+ end
234
+
235
+ def nil.__and?
236
+ return NQObject.new
237
+ end
238
+
239
+ def false._?
240
+ return NQObject.new
241
+ end
242
+
243
+ def false.__and?
244
+ return NQObject.new
245
+ end
246
+
247
+
248
+
249
+
250
+ class QObject
251
+ instance_methods.each { |m|
252
+ if !["__id__", "__send__", "object_id"].include? m.to_s
253
+ undef_method m
254
+ end
255
+ }
256
+ def initialize obj, mode = true
257
+ @mode = mode
258
+ @obj = obj
259
+ end
260
+ def __obj
261
+ @obj
262
+ end
263
+ def method_missing (name, *args, **opts, &bl)
264
+ if @obj != nil
265
+ hasQObj = false
266
+ qobj = nil
267
+ args.each_with_index do |e, i|
268
+ case e
269
+ when QObject
270
+ hasQObj = true
271
+ args[i] = e.__obj
272
+ qobj = e.__obj
273
+ when NQObject
274
+ return NQObject::Obj
275
+ end
276
+ end
277
+ if @obj.is_a? Binding
278
+ args = args.map{|e| "ObjectSpace._id2ref(#{e.__id__})"}
279
+ if bl
280
+ args.push "&ObjectSpace._id2ref(#{bl.__id__})"
281
+ end
282
+ res = @obj.eval("#{name} #{args.join(', ')}")
283
+ else
284
+ res = @obj.__send__(name, *args, &bl)
285
+ end
286
+ if hasQObj
287
+ return qobj
288
+ else
289
+ res = res ? true : false
290
+ if res ^ !@mode
291
+ @obj
292
+ else
293
+ NQObject::Obj
294
+ end
295
+ end
296
+ else
297
+ NQObject::Obj
298
+ end
299
+ end
300
+ def respond_to? name, include_all = false
301
+ true
302
+ end
303
+ def [] (label)
304
+ if @obj.method(label).call ^ !@mode
305
+ @obj
306
+ else
307
+ nil
308
+ end
309
+ end
310
+ end
311
+
312
+
313
+
314
+
315
+
316
+ class Numeric
317
+ def roundup(d=0)
318
+ x = 10**d
319
+ if self > 0
320
+ (self * x).ceil.quo(x)
321
+ else
322
+ (self * x).floor.quo(x)
323
+ end
324
+ end
325
+
326
+ def rounddown(d=0)
327
+ x = 10**d
328
+ if self < 0
329
+ (self * x).ceil.quo(x)
330
+ else
331
+ (self * x).floor.quo(x)
332
+ end
333
+ end
334
+
335
+ def roundoff(d=0)
336
+ x = 10**d
337
+ if self < 0
338
+ (self * x - 0.5).ceil.quo(x)
339
+ else
340
+ (self * x + 0.5).floor.quo(x)
341
+ end
342
+ end
343
+ end
344
+
345
+
346
+ class Integer
347
+ def kill arg = :TERM
348
+ Process.kill arg, self
349
+ end
350
+ def waitpid
351
+ Process.waitpid self
352
+ end
353
+ end
354
+
355
+ class Array
356
+ def kill arg = :TERM
357
+ if self.size > 0
358
+ Process.kill arg, *self
359
+ end
360
+ end
361
+ end
362
+
363
+
364
+ module Code
365
+ refine Kernel do
366
+ class Code__
367
+ def first?
368
+ cur = (@clause_variables ||= {})[caller(1)]
369
+ if cur != :first_passed
370
+ @clause_variables[caller(1)] = :first_passed
371
+ if block_given?
372
+ yield
373
+ else
374
+ true
375
+ end
376
+ else
377
+ nil
378
+ end
379
+ end
380
+ def redo
381
+ throw @symbol, :redo
382
+ end
383
+ def break
384
+ throw @symbol, :break
385
+ end
386
+ def to_proc
387
+ @proc
388
+ end
389
+ def to_sym
390
+ @symbol ||= inspect.to_sym
391
+ end
392
+ def initialize &bl
393
+ @proc = bl
394
+ end
395
+ end
396
+ def Code
397
+ c = Code__.new
398
+ loop do
399
+ case catch(c.to_sym){yield c}
400
+ when :redo
401
+ redo
402
+ when :break
403
+ break
404
+ end
405
+ break
406
+ end
407
+ end
408
+ end
409
+ end
410
+
411
+
412
+ if !defined? CYGWIN
413
+ CYGWIN = (`/bin/uname` =~ /CYGWIN/)
414
+ end
415
+ if CYGWIN
416
+ if !defined?(CYGADMIN)
417
+ testFName = "/var/tmp/__test_admin__#{rand(10000000000)}"
418
+ begin
419
+ File.open testFName, "w" do |fw|
420
+ File.chmod 0666, testFName
421
+ end
422
+ isAdmin = false
423
+ begin
424
+ require 'etc'
425
+ File.chown Etc.getpwnam("SYSTEM").uid, Etc.getgrnam("Administrators").gid, testFName
426
+ isAdmin = true
427
+ rescue
428
+ end
429
+ CYGADMIN = isAdmin
430
+ ensure
431
+ File.delete testFName
432
+ end
433
+ end
434
+ end
435
+
436
+
437
+ class Reexception < Exception
438
+ def initialize
439
+ @reexception = $!
440
+ end
441
+ def reraise
442
+ $! = @reexception
443
+ raise
444
+ end
445
+ end
446
+
447
+
448
+ class String
449
+ #def -@
450
+ # first = false
451
+ # findent = nil
452
+ # ret = ""
453
+ # self.each_line do |e|
454
+ # if e == "\n" && !findent
455
+ # next
456
+ # end
457
+ # if !findent
458
+ # e =~ /^\s+/
459
+ # findent = ($& || "")
460
+ # end
461
+ # if e =~ /^#{Regexp.escape findent}/
462
+ # ret += $'
463
+ # else
464
+ # ret += e
465
+ # end
466
+ # end
467
+ # if ret[-1] != ?\n && ret =~ /[\t ]+$/
468
+ # ret = $`
469
+ # end
470
+ # ret
471
+ #end
472
+ def first_line
473
+ if self =~ /\n/
474
+ $`
475
+ else
476
+ self
477
+ end
478
+ end
479
+ def first_section
480
+ i = self.index("\n\n")
481
+ if i
482
+ self[0..i]
483
+ else
484
+ self
485
+ end
486
+ end
487
+ def significant?
488
+ strip != ""
489
+ end
490
+ end
491
+
492
+
493
+ def nil.significant?
494
+ false
495
+ end
496
+
497
+ class Array
498
+ def significant?
499
+ !empty?
500
+ end
501
+ end
502
+
503
+ class Integer
504
+ def significant?
505
+ self != 0
506
+ end
507
+ end
508
+
509
+
510
+ require 'digest/md5'
511
+
512
+ class String
513
+ def md5sum
514
+ Digest::MD5.hexdigest(self)
515
+ end
516
+ end
517
+
518
+
519
+ class String
520
+ def refeed
521
+ if self[-1] != ?\n
522
+ self + "\n"
523
+ else
524
+ self
525
+ end
526
+ end
527
+ end
528
+
529
+ begin
530
+ require 'sync'
531
+
532
+
533
+ class FreeFormatCoHash
534
+ include Sync_m rescue nil
535
+ class Item
536
+ attr :lastUsed
537
+ def initialize (index, parent)
538
+ @index = index
539
+ @props = Hash.new
540
+ @parent = parent
541
+ @lastUsed = Time.now
542
+ end
543
+ def method_missing (name, *args)
544
+ @lastUsed = Time.now
545
+ if name.to_s[-1] == ?=
546
+ tmp = name.to_s.chop
547
+ @props[tmp] ||= args[0]
548
+ @parent.propList(tmp)[args[0]] = self
549
+ @props[tmp]
550
+ else
551
+ @props[name.to_s]
552
+ end
553
+ end
554
+ def respond_to_missing? name, include_private
555
+ if name.to_s[-1] == ?=
556
+ true
557
+ else
558
+ if @props[name.to_s]
559
+ true
560
+ else
561
+ false
562
+ end
563
+ end
564
+ end
565
+ def del
566
+ @props.each do |k, v|
567
+ @parent.propList(k).delete v
568
+ end
569
+ end
570
+ end
571
+ def initialize
572
+ super
573
+ @propList = Hash.new
574
+ @list = Hash.new
575
+ end
576
+ def [] (index)
577
+ synchronize do
578
+ @list[index] ||= Item.new(index, self)
579
+ item = @list[index]
580
+ end
581
+ end
582
+ def delete (key)
583
+ synchronize do
584
+ @list[key].del
585
+ @list.delete key
586
+ end
587
+ end
588
+ def propList (propName)
589
+ synchronize do
590
+ @propList[propName] ||= Hash.new
591
+ end
592
+ end
593
+ def method_missing (name, *args)
594
+ synchronize do
595
+ if name.to_s[-1] == ?=
596
+ raise Exception.new("cannot use method #{name}\n")
597
+ end
598
+ @propList[name.to_s]
599
+ end
600
+ end
601
+ def respond_to_missing? name, include_private
602
+ if @propList[name.to_s]
603
+ true
604
+ else
605
+ false
606
+ end
607
+ end
608
+ end
609
+ rescue Exception
610
+ end
611
+
612
+
613
+ class Array
614
+ def prefix_join (sep, capsule = nil)
615
+ ret = ""
616
+ each do |e|
617
+ ret += e + sep
618
+ end
619
+ if ret != "" && capsule != nil
620
+ ret = capsule.split(/\{\}/).join(ret)
621
+ end
622
+ ret
623
+ end
624
+ def prefix_cond_join (sep, capsule = nil)
625
+ ret = ""
626
+ each do |e|
627
+ if e != nil && e.strip != ""
628
+ ret += e.strip + sep
629
+ end
630
+ end
631
+ if ret != "" && capsule != nil
632
+ ret = capsule.split(/\{\}/).join(ret)
633
+ end
634
+ ret
635
+ end
636
+ def cond_join (sep = " ", capsule = nil)
637
+ ret = ""
638
+ arr = []
639
+ each do |e|
640
+ if e != nil && e.strip != ""
641
+ arr.push e.strip
642
+ end
643
+ end
644
+ ret = arr.join(sep)
645
+ if ret != "" && capsule != nil
646
+ ret = capsule.split(/\{\}/).join(ret)
647
+ end
648
+ ret
649
+ end
650
+ def each2 hasLast = false
651
+ (0 ... size / 2).each do |i|
652
+ yield self[i * 2], self[i * 2 + 1]
653
+ end
654
+ if hasLast && size % 2 == 1
655
+ yield self[-1], nil
656
+ end
657
+ end
658
+ def each2by1
659
+ (0 ... size - 1).each do |i|
660
+ yield self[i], self[i + 1]
661
+ end
662
+ end
663
+ end
664
+
665
+
666
+ class AnonStruct
667
+ @@astructs = {}
668
+ def AnonStruct.[] (hash)
669
+ hk = hash.keys
670
+ if !(as = @@astructs[hk])
671
+ @@astructs[hk] = as = Class.new(Array)
672
+ hk.each_index do |i|
673
+ as.instance_eval %{
674
+ define_method :#{hk[i]} do
675
+ self[#{i}]
676
+ end
677
+ define_method :#{hk[i]}= do |arg|
678
+ self[#{i}] = arg
679
+ end
680
+ }
681
+ end
682
+ args = hk.map{ |e| e.to_s }.join(", ")
683
+ as.instance_eval %{
684
+ define_method :initialize do |#{args}|
685
+ super()
686
+ push #{args}
687
+ end
688
+ }
689
+ end
690
+ as.new(*hash.values)
691
+ end
692
+ end
693
+
694
+
695
+ module UnderscoreEscaper
696
+ CHAR_w = "abcdefghijklmnopqrstuvwxyzABCDEFGHI"
697
+ CHAR_W = ' !"#$%&\'()*+,-./:;<=>?@[\\]^_{|}~^?'
698
+ module_function
699
+ def esc_table (c)
700
+ CHAR_w[CHAR_W.index(c)].chr
701
+ end
702
+ def unesc_table (c)
703
+ CHAR_W[CHAR_w.index(c)].chr
704
+ end
705
+ def escape (arg)
706
+ if arg == nil
707
+ "_Z_"
708
+ else
709
+ arg.gsub /_|\W/ do |e|
710
+ "_" + esc_table(e) + "_"
711
+ end
712
+ end
713
+ end
714
+ def unescape (arg)
715
+ if arg == "_Z_"
716
+ nil
717
+ else
718
+ arg.gsub /_(\w)_/ do
719
+ unesc_table($1)
720
+ end
721
+ end
722
+ end
723
+ end
724
+
725
+
726
+ class CommandLine
727
+ class Opt
728
+ attr :toShort
729
+ attr :argNum
730
+ attr :name
731
+ attr :redirectOpts
732
+ def initialize (n, s, an, ro = nil)
733
+ @name = n
734
+ @toShort = s
735
+ @argNum = an
736
+ @redirectOpts = ro
737
+ end
738
+ def isRedirector?
739
+ @argNum == -1
740
+ end
741
+ def isShort?
742
+ @name.size == 2
743
+ end
744
+ def isLong?
745
+ !isShort?
746
+ end
747
+ def Opt.createOpt (exp, agNum, redirectOpts = nil)
748
+ ret = []
749
+ if !exp || exp.size == 0
750
+ return []
751
+ end
752
+ hasDefault = false
753
+ if exp =~ /\[\?\]$/
754
+ exp = $`
755
+ hasDefault = true
756
+ if agNum != 1
757
+ raise Exception.new("cannot use default argument for option, #{exp}")
758
+ end
759
+ end
760
+ arr = exp.split /,/
761
+ toShort = nil
762
+ arr.each do |expr|
763
+ lopt = nil
764
+ sopt = nil
765
+ if expr =~ /\((.)\)/
766
+ sopt = $1
767
+ if $` && $`.strip != ""
768
+ lopt = $`
769
+ elsif $' && $'.strip != ""
770
+ lopt = $'
771
+ end
772
+ elsif expr =~ /\[(.)\]/
773
+ sopt = $1
774
+ tlopt = ""
775
+ if $` && $`.strip != ""
776
+ tlopt = $`
777
+ end
778
+ tlopt += $1
779
+ if $' && $'.strip != ""
780
+ tlopt += $'
781
+ end
782
+ if tlopt != ""
783
+ lopt = tlopt
784
+ end
785
+ elsif expr.size == 1
786
+ sopt = expr
787
+ lopt = nil
788
+ else
789
+ sopt = nil
790
+ lopt = expr
791
+ end
792
+ lopt = nil if lopt == ""
793
+ sopt = nil if sopt == ""
794
+ if sopt
795
+ toShort ||= "-" + sopt[0].chr
796
+ sopt.each_byte do |c|
797
+ ret.push Opt.new("-" + c.chr, toShort, agNum, redirectOpts)
798
+ end
799
+ end
800
+ if lopt
801
+ if !toShort
802
+ if sopt
803
+ toShort = "-" + sopt[0].chr
804
+ else
805
+ toShort = "--" + lopt
806
+ end
807
+ end
808
+ if hasDefault
809
+ ret.push Opt.new("--" + lopt, toShort, -1, redirectOpts)
810
+ else
811
+ ret.push Opt.new("--" + lopt, toShort, agNum, redirectOpts)
812
+ end
813
+ end
814
+ end
815
+ ret
816
+ end
817
+ end
818
+ class Error < ArgumentError
819
+ end
820
+ def getOptList (noArgOpts, oneArgOpts, twoArgOpts, redirector)
821
+ require "Yk/set"
822
+ ret = KeyedSet.new :name
823
+ [[noArgOpts, 0], [oneArgOpts, 1], [twoArgOpts, 2]].each do |argOpts, agNum|
824
+ argOpts.each do |e|
825
+ Opt.createOpt(e, agNum).each do |o|
826
+ ret.insert o
827
+ end
828
+ end
829
+ end
830
+ if redirector
831
+ Opt.createOpt(redirector[0], -1, redirector[1..-1]).each do |o|
832
+ ret.insert o
833
+ end
834
+ end
835
+ ret
836
+ end
837
+ def initialize (*args)
838
+ require 'Yk/generator__'
839
+ if !args[0].is_a? Object::Generator_
840
+ noArgOpts, oneArgOpts, twoArgOpts, redirector, argv = args
841
+ else
842
+ g = args.shift
843
+ yield self
844
+ noArgOpts, oneArgOpts, twoArgOpts, redirector = args
845
+ end
846
+ noArgOpts = !noArgOpts.is_a?(Array) ? [noArgOpts] : noArgOpts
847
+ oneArgOpts = !oneArgOpts.is_a?(Array) ? [oneArgOpts] : oneArgOpts
848
+ twoArgOpts = !twoArgOpts.is_a?(Array) ? [twoArgOpts] : twoArgOpts
849
+ @optList = getOptList(noArgOpts, oneArgOpts, twoArgOpts, redirector)
850
+ @opt = Hash.new
851
+ @args = []
852
+ if !g
853
+ if !argv
854
+ g = ARGV.generator__ do
855
+ return
856
+ end
857
+ else
858
+ g = argv.generator__ do
859
+ return
860
+ end
861
+ end
862
+ end
863
+ while true
864
+ if +g != "-" && +g =~ /^\-/
865
+ if +g =~ /^\--/ && +g =~ /\=/
866
+ if s = @optList[$`]
867
+ if s.argNum == 1 || s.argNum == -1
868
+ (@opt[s.toShort] ||= []).push $'
869
+ else
870
+ raise Error.new("cannot use '=' for option '#{s}': number of arguments are not compatible (must be 1)")
871
+ end
872
+ else
873
+
874
+ end
875
+ elsif s = @optList[+g]
876
+ if s.isRedirector?
877
+ g.inc
878
+ self.class.new(g, *s.redirectOpts) do |cmd|
879
+ @opt[s.toShort] = cmd
880
+ end
881
+ elsif s.argNum >= 1 && s.isShort?
882
+ s.argNum.times do
883
+ g.inc
884
+ (@opt[s.toShort] ||= []).push +g
885
+ end
886
+ elsif s.argNum == -1
887
+ (@opt[s.toShort] ||= []).push nil
888
+ elsif s.argNum == 0
889
+ @opt[s.toShort] ||= 0
890
+ @opt[s.toShort] += 1
891
+ else
892
+ raise Error.new("option `#{+g}' must have argment with equal or use short option.")
893
+ end
894
+ elsif (+g)[1] != ?- && (+g).size >= 3
895
+ rpos = (+g).size - 1
896
+ (+g)[1..-1].split("").each do |e|
897
+ rpos -= 1
898
+ tmp = "-" + e
899
+ if !(s = @optList[tmp])
900
+ raise Error.new("option `#{tmp}' is not specified.")
901
+ elsif s.argNum != 0 && rpos != 0
902
+ raise Error.new("option `#{tmp}' must have argment.")
903
+ end
904
+ if s.argNum >= 1
905
+ s.argNum.times do
906
+ g.inc
907
+ (@opt[s.toShort] ||= []).push +g
908
+ end
909
+ else
910
+ @opt[s.toShort] ||= 0
911
+ @opt[s.toShort] += 1
912
+ end
913
+ end
914
+ else
915
+ raise Error.new("option `#{+g}' is not specified.")
916
+ end
917
+ g.inc
918
+ next
919
+ end
920
+ @args.push +g
921
+ g.inc
922
+ end
923
+ end
924
+ def [] (arg)
925
+ if arg.is_a? Integer
926
+ @args[arg]
927
+ else
928
+ if @opt[arg] == nil
929
+ if !(tmp = @optList[arg])
930
+ nil
931
+ elsif tmp.argNum >= 1
932
+ []
933
+ else
934
+ 0
935
+ end
936
+ else
937
+ @opt[arg]
938
+ end
939
+ end
940
+ end
941
+ def []= (arg, v)
942
+ if arg.is_a? Integer
943
+ @args[arg] = v
944
+ else
945
+ @opt[arg] = v
946
+ end
947
+ end
948
+ def shift
949
+ @args.shift
950
+ end
951
+ def pop
952
+ @args.pop
953
+ end
954
+ def push (*args)
955
+ @args.push *args
956
+ end
957
+ def unshift (*args)
958
+ @args.unshift *args
959
+ end
960
+ def size
961
+ @args.size
962
+ end
963
+ def each
964
+ @args.each do |e|
965
+ yield e
966
+ end
967
+ end
968
+ def slice (*args)
969
+ @args.slice(*args)
970
+ end
971
+ def slice! (*args)
972
+ @args.slice!(*args)
973
+ end
974
+ def deleteOpt (arg)
975
+ @opt.delete arg
976
+ end
977
+ def all_options
978
+ arr = []
979
+ @opt.each do |k, v|
980
+ if k.size > 2
981
+ head = "-" + k
982
+ eqlMode = true
983
+ else
984
+ head = k
985
+ eqlMode = false
986
+ end
987
+ if v.is_a? Integer
988
+ v.times do
989
+ arr.push head
990
+ end
991
+ else
992
+ v.each do |e|
993
+ if eqlMode
994
+ arr.push head + "=" + e
995
+ else
996
+ arr.push head
997
+ arr.push e
998
+ end
999
+ end
1000
+ end
1001
+ end
1002
+ arr
1003
+ end
1004
+ def to_a
1005
+ arr = all_options
1006
+ arr += @args
1007
+ arr
1008
+ end
1009
+ def join (arg)
1010
+ @args.join(arg)
1011
+ end
1012
+ def args
1013
+ @args.clone
1014
+ end
1015
+ def self.[] (arg)
1016
+ begin
1017
+ new(arg)
1018
+ rescue Error => e
1019
+ STDERR.write e.to_s.ln
1020
+ exit 1
1021
+ end
1022
+ end
1023
+ end
1024
+
1025
+
1026
+ def nil.optarg (opt)
1027
+ self
1028
+ end
1029
+
1030
+
1031
+ def nil.& (opt)
1032
+ self
1033
+ end
1034
+
1035
+
1036
+ class String
1037
+ def optarg (arg)
1038
+ if arg != nil && (tmp = self.strip) != "" && (tmp2 = arg.to_s.strip) != ""
1039
+ tmp + " " + tmp2
1040
+ else
1041
+ ""
1042
+ end
1043
+ end
1044
+ def & (arg)
1045
+ optarg(arg)
1046
+ end
1047
+ def ln
1048
+ self.chomp + "\n"
1049
+ end
1050
+ def ln!
1051
+ replace(chomp + "\n")
1052
+ end
1053
+ end
1054
+
1055
+
1056
+ def requireSib (*args)
1057
+ args.each do |e|
1058
+ if e !~ /^\//
1059
+ e = File.dirname(e) + "/" + File.basename(e, ".rb") + ".rb"
1060
+ if File.readable?(tmp = File.dirname($0) + "/" + e)
1061
+ require tmp
1062
+ end
1063
+ else
1064
+ require e
1065
+ end
1066
+ end
1067
+ end
1068
+
1069
+
1070
+ class String
1071
+ def underscore_escape
1072
+ UnderscoreEscaper.escape(self)
1073
+ end
1074
+ def underscore_unescape
1075
+ UnderscoreEscaper.unescape(self)
1076
+ end
1077
+ end
1078
+
1079
+
1080
+ def nil.underscore_escape
1081
+ "_Z_"
1082
+ end
1083
+
1084
+
1085
+ require 'Yk/__defun__'
1086
+
1087
+
1088
+ class String
1089
+ def split_chunk (expr)
1090
+ s = self
1091
+ items = []
1092
+ while s && s =~ expr
1093
+ if $` && $` != ""
1094
+ items.push $`
1095
+ end
1096
+ items.push $&
1097
+ s = $'
1098
+ end
1099
+ if s && s != ""
1100
+ items.push s
1101
+ end
1102
+ items
1103
+ end
1104
+ def strip_comment! arg = nil
1105
+ arg == "" && arg = "#"
1106
+ if arg.is_a? String
1107
+ arg.__defun__ :__pre, self[/^\s*/]
1108
+ arg.__defun__ :__post, self[/\s*(#{Regexp.escape arg}[^\n]*|)(\n|$)/]
1109
+ elsif arg
1110
+ raise ArgumentError.new("argument should be a String")
1111
+ end
1112
+ gsub! /#{arg ? Regexp.escape(arg) : "\\#"}[^\n]*(\n|$)/, '\1'
1113
+ strip!
1114
+ end
1115
+ def strip_comment arg = nil
1116
+ arg == "" && arg = "#"
1117
+ if arg.is_a? String
1118
+ arg.__defun__ :__pre, self[/^\s*/]
1119
+ arg.__defun__ :__post, self[/\s*(#{Regexp.escape arg}[^\n]*|)(\n|$)/]
1120
+ elsif arg
1121
+ raise ArgumentError.new("argument should be a String")
1122
+ end
1123
+ ln = gsub(/#{arg ? Regexp.escape(arg) : "\\#"}[^\n]*(\n|$)/, '\1')
1124
+ ln.strip
1125
+ end
1126
+ def recomment arg
1127
+ ret = self
1128
+ if arg.respond_to? :__pre
1129
+ ret = arg.__pre + ret if arg.__pre
1130
+ end
1131
+ if arg.respond_to? :__post
1132
+ ret = ret + arg.__post if arg.__post
1133
+ end
1134
+ ret
1135
+ end
1136
+ end
1137
+
1138
+
1139
+ class Array
1140
+ def chomp!
1141
+ each do |e|
1142
+ e.chomp!
1143
+ end
1144
+ self
1145
+ end
1146
+ end
1147
+
1148
+
1149
+
1150
+
1151
+
1152
+ module Process
1153
+ SignalList = Hash.new
1154
+ Signal.list.each do |k, v|
1155
+ SignalList["SIG" + k] = k.to_sym
1156
+ SignalList[("SIG" + k).to_sym] = k.to_sym
1157
+ SignalList[k.to_sym] = k.to_sym
1158
+ SignalList[k] = k.to_sym
1159
+ SignalList[v] = k.to_sym
1160
+ end
1161
+ def self.normalizeSignal (arg)
1162
+ if (tmp = SignalList[arg]) == nil
1163
+ raise ArgumentError.new("signal '#{arg}' is not defined")
1164
+ end
1165
+ tmp
1166
+ end
1167
+ DOTRAP_BLOCKS = Hash.new
1168
+ class ProcWithLocal < Proc
1169
+ def initialize (*args, &bl)
1170
+ super &bl
1171
+ @args = args
1172
+ end
1173
+ def call (*args)
1174
+ super *(@args + args)
1175
+ end
1176
+ end
1177
+ class TrapArr < Array
1178
+ def exit?
1179
+ @exit
1180
+ end
1181
+ def default?
1182
+ @default
1183
+ end
1184
+ attr_writer :exit, :default
1185
+ end
1186
+ DOTRAP_LIST = Hash.new do |h, k|
1187
+ h[k] = TrapArr.new
1188
+ end
1189
+ Signal.list.keys.each do |sig|
1190
+ DOTRAP_BLOCKS[sig.to_sym] = Proc.new do |lb|
1191
+ lb = normalizeSignal(lb)
1192
+ Signal.trap lb do end
1193
+ begin
1194
+ DOTRAP_LIST[lb].each do |e|
1195
+ if e.is_a? Proc
1196
+ e.call lb
1197
+ elsif e.is_a? String
1198
+ eval(e)
1199
+ else
1200
+ e.to_proc.call lb
1201
+ end
1202
+ end
1203
+ if DOTRAP_LIST[lb].default?
1204
+ Signal.trap lb, "DEFAULT"
1205
+ Process.kill lb, $$
1206
+ end
1207
+ if DOTRAP_LIST[lb].exit?
1208
+ exit
1209
+ end
1210
+ ensure
1211
+ Signal.trap lb, DOTRAP_BLOCKS[lb]
1212
+ end
1213
+ end
1214
+ end
1215
+ def self.addTrap (*args, &bl)
1216
+ inserter = Proc.new do |s, b|
1217
+ if ![nil, "SIG_IGN", "IGNORE", "", "SIG_DFL"].include? b
1218
+ if b == "EXIT"
1219
+ DOTRAP_LIST[s].exit = true
1220
+ elsif b == "DEFAULT"
1221
+ DOTRAP_LIST[s].default = true
1222
+ else
1223
+ DOTRAP_LIST[s].push bl
1224
+ end
1225
+ end
1226
+ end
1227
+ !bl and bl = args.pop
1228
+ args.size == 0 and args = Process::DOTRAP_BLOCKS.keys.map{|e| e.to_sym}.select{|e| e != :VTALRM}
1229
+ args.each do |e|
1230
+ e = e.to_sym
1231
+ if !DOTRAP_BLOCKS[e]
1232
+ raise ArgumentError.new("unknown signal name #{e}")
1233
+ end
1234
+ if !CYGWIN || e != :EXIT
1235
+ prev = Signal.trap(e, "SIG_IGN")
1236
+ end
1237
+ if prev != DOTRAP_BLOCKS[e]
1238
+ inserter.call e, prev
1239
+ end
1240
+ inserter.call e, bl
1241
+ Signal.trap(e, &DOTRAP_BLOCKS[e])
1242
+ end
1243
+ end
1244
+ def self.removeTrap (*args)
1245
+ toRemove = args.pop
1246
+ args.size == 0 and args = DOTRAP_BLOCKS.keys
1247
+ args.each do |e|
1248
+ if !DOTRAP_BLOCKS[e]
1249
+ raise ArgumentError.new("unknown signal name #{e}")
1250
+ end
1251
+ if toRemove == "EXIT"
1252
+ DOTRAP_LIST[e.to_sym].exit = false
1253
+ elsif toRemove == "DEFAULT"
1254
+ DOTRAP_LIST[e.to_sym].exit = false
1255
+ end
1256
+ DOTRAP_LIST[e.to_sym].delete toRemove
1257
+ end
1258
+ end
1259
+ @@set_kill_with_children = false
1260
+ def self.set_kill_with_children (*args)
1261
+ if !@@set_kill_with_children
1262
+ @@set_kill_with_children = true
1263
+ setpgrp rescue nil
1264
+ addTrap *args do |e|
1265
+ if (tmp = SignalList[e]) != :EXIT
1266
+ begin
1267
+ trap e, "IGNORE"
1268
+ begin
1269
+ Process.kill e, 0
1270
+ rescue
1271
+ end
1272
+ ensure
1273
+ trap e, &DOTRAP_BLOCKS[tmp]
1274
+ end
1275
+ end
1276
+ end
1277
+ at_exit do
1278
+ begin
1279
+ trap :TERM, "IGNORE"
1280
+ begin
1281
+ Process.kill :TERM, 0
1282
+ rescue
1283
+ end
1284
+ ensure
1285
+ trap :TERM, &DOTRAP_BLOCKS[:TERM]
1286
+ end
1287
+ end
1288
+ end
1289
+ end
1290
+ end
1291
+
1292
+
1293
+ class String
1294
+ def getDefinition (id)
1295
+ if id.is_a? Array
1296
+ seed = id.map{ |e| Regexp.escape(e) }.join("|")
1297
+ if self =~ /^\s*(#{seed})\s*\=\s*([^\s]+)/
1298
+ yield $1, $2
1299
+ end
1300
+ else
1301
+ if self =~ /^\s*#{Regexp.escape id}\s*\=\s*([^\s]+)/
1302
+ ret = $1
1303
+ ret.sub! /\#.*/, ""
1304
+ ret
1305
+ else
1306
+ if strip_comment == ""
1307
+ nil
1308
+ elsif (tmp = strip_comment.split).size == 1
1309
+ yield tmp[0], ""
1310
+ end
1311
+ end
1312
+ end
1313
+ end
1314
+ end
1315
+
1316
+
1317
+ class String
1318
+ def system (*args, **opts)
1319
+ if args.significant?
1320
+ Kernel.system *([self] + args), **opts
1321
+ else
1322
+ Kernel.system self
1323
+ end
1324
+ end
1325
+ def exec (*args, **opts)
1326
+ if args.significant?
1327
+ Kernel.exec *([self] + args), **opts
1328
+ else
1329
+ Kernel.exec self
1330
+ end
1331
+ end
1332
+ end
1333
+
1334
+ module Etc
1335
+ class User
1336
+ def self.root? arg
1337
+ [:root, 0, "root"].include? arg
1338
+ end
1339
+ %W{name uid shell dir}.each do |m|
1340
+ eval <<~END
1341
+ def self.#{m} arg
1342
+ require 'etc'
1343
+ case arg
1344
+ when Integer
1345
+ Etc.getpwuid(arg)&.#{m}
1346
+ when String, Symbol
1347
+ Etc.getpwnam(arg.to_s)&.#{m}
1348
+ when nil
1349
+ Etc.getpwuid(Process.euid)&.#{m}
1350
+ else
1351
+ raise ArgumentError("\#{arg} is niether Integer not String")
1352
+ end
1353
+ end
1354
+ END
1355
+ end
1356
+ def self.home arg
1357
+ dir arg
1358
+ end
1359
+ def self.id arg
1360
+ uid arg
1361
+ end
1362
+ def initialize ent
1363
+ @ent = ent
1364
+ end
1365
+ %W{name passwd uid gid gecos dir shell change quota age class comment expire}.each do |e|
1366
+ eval %{
1367
+ def #{e}
1368
+ @ent.#{e}
1369
+ end
1370
+ }
1371
+ end
1372
+ def home
1373
+ dir
1374
+ end
1375
+ def password
1376
+ passwd
1377
+ end
1378
+ def self.each &bl
1379
+ begin
1380
+ if bl
1381
+ loop do
1382
+ yield new(Etc.getpwent || break)
1383
+ end
1384
+ nil
1385
+ else
1386
+ ret = []
1387
+ loop do
1388
+ ret.push(Etc.getpwent || break)
1389
+ end
1390
+ ret
1391
+ end
1392
+ ensure
1393
+ Etc.endpwent
1394
+ end
1395
+ end
1396
+ end
1397
+
1398
+ [ %W{EUser euid},
1399
+ %W{RUser uid}
1400
+ ].each do |cls, id|
1401
+ eval <<~ALLED
1402
+ class #{cls} # effective user
1403
+ def self.root?
1404
+ Process.#{id} == 0
1405
+ end
1406
+ def self.current? arg
1407
+ if arg
1408
+ Process.#{id} == User.uid(arg)
1409
+ else
1410
+ true
1411
+ end
1412
+ end
1413
+ %W{name uid shell dir}.each do |m|
1414
+ eval <<~END
1415
+ def self.\#{m} arg = nil
1416
+ if !arg || User.id(Process.#{id}) == User.id(arg)
1417
+ User.\#{m}(Process.#{id})
1418
+ end
1419
+ end
1420
+ END
1421
+ end
1422
+ def self.home arg = nil
1423
+ dir arg
1424
+ end
1425
+ def self.id arg = nil
1426
+ uid arg
1427
+ end
1428
+ end
1429
+ ALLED
1430
+ end
1431
+
1432
+
1433
+ class LUser # login user
1434
+ def self.getLoginUserId
1435
+ User.id(ENV['SUDU_USER'] || ENV['USER'] || RUser.name)
1436
+ end
1437
+ def self.root?
1438
+ User.root? getLoginUserId
1439
+ end
1440
+ %W{name uid shell dir}.each do |m|
1441
+ eval <<~END
1442
+ def self.#{m} arg = nil
1443
+ if !arg || (lid = getLoginUserId) == User.id(arg)
1444
+ User.#{m}(lid || getLoginUserId)
1445
+ end
1446
+ end
1447
+ END
1448
+ end
1449
+ def self.home arg = nil
1450
+ dir arg
1451
+ end
1452
+ def self.id arg = nil
1453
+ uid arg
1454
+ end
1455
+ end
1456
+ end
1457
+
1458
+ class Array
1459
+ protected
1460
+ def __command_tz__2 mode, env, opts, euid = nil, ruid = nil
1461
+ prc = Proc.new do
1462
+ Process.euid = euid if euid
1463
+ Process.uid = ruid if ruid
1464
+ if env
1465
+ Kernel.exec env, *self, **opts
1466
+ elsif opts[:env]
1467
+ o = opts.clone
1468
+ o.delete(:env)
1469
+ Kernel.exec opts[:env], *self, **o
1470
+ else
1471
+ Kernel.exec *self, **opts
1472
+ end
1473
+ end
1474
+ case mode
1475
+ when :system
1476
+ pid = fork do
1477
+ prc.call
1478
+ end
1479
+ Process.waitpid pid
1480
+ case $?.exitstatus
1481
+ when 0
1482
+ return true
1483
+ when Integer
1484
+ return false
1485
+ else
1486
+ return nil
1487
+ end
1488
+ when :exec
1489
+ prc.call
1490
+ end
1491
+ end
1492
+ def __command_tz__ mode, a, b, opts
1493
+ if a.is_a? Hash
1494
+ env, uname = a, b
1495
+ elsif b.is_a? Hash
1496
+ env, uname = b, a
1497
+ elsif !a.nil?
1498
+ uname, env = a, b
1499
+ elsif !b.nil?
1500
+ uname, env = b, a
1501
+ end
1502
+ if opts[:user]
1503
+ o = opts.clone
1504
+ uname = o.delete(:user)
1505
+ opts = o
1506
+ end
1507
+ if opts[:ruser]
1508
+ o = opts.clone
1509
+ runame = o.delete(:ruser)
1510
+ opts = o
1511
+ end
1512
+ if opts[:euser]
1513
+ o = opts.clone
1514
+ euname = o.delete(:euser)
1515
+ opts = o
1516
+ end
1517
+ if Etc::EUser.current? uname
1518
+ __command_tz__2 mode, env, opts
1519
+ elsif Etc::User.root? uname
1520
+ require "shellwords"
1521
+ if (File.executable?(tmp = "/usr/sbin/cansudo") && system(tmp) && $? == 0 && STDIN.tty?) or "/etc/group".read =~ /\nwheel|sudo:.*\b(#{Regexp.escape Etc.getpwuid(Process.euid).name})\b/
1522
+ ["sudo", *self].__command_tz__2 mode, env, opts
1523
+ else
1524
+ ["su", "-c", Shellwords.join(self)].__command_tz__2 mode, env, opts
1525
+ end
1526
+ else
1527
+ if Process.euid == 0
1528
+ __command_tz__2 mode, env, opts, Etc::User.id(euname||uname), Etc::User.id(runame||uname)
1529
+ else
1530
+ ["su", Etc::User.name(uname), "-c", Shellwords.join(self)].__command_tz__2 mode, env, opts
1531
+ end
1532
+ end
1533
+ end
1534
+ public
1535
+ def system a = nil, b = nil, **opts
1536
+ __command_tz__ :system, a, b, opts
1537
+ end
1538
+ def exec a = nil, b = nil, **opts
1539
+ __command_tz__ :exec, a, b, opts
1540
+ end
1541
+ def popen (mode = "r")
1542
+ require 'Yk/shellquote'
1543
+ IO.popen condSQuote, mode do |e|
1544
+ yield e
1545
+ end
1546
+ end
1547
+ end
1548
+
1549
+
1550
+ class Object
1551
+ def __context_var__ (label, value)
1552
+ require 'Yk/__defun__'
1553
+ ar = (@__context_var_arr__ ||= Hash.new{|h, k| h[k] = Hash.new{|h2, k2| h2[k2] = []}})[label][Thread.current]
1554
+ if !respond_to? label
1555
+ __defun__ label do
1556
+ @__context_var_arr__[label][Thread.current][-1]
1557
+ end
1558
+ end
1559
+ ar.push value
1560
+ ret = yield
1561
+ ar.pop
1562
+ ret
1563
+ end
1564
+ end
1565
+
1566
+
1567
+ def Process.set_detach (pid, &bl)
1568
+ @@datachList ||= Hash.new { |h, k|
1569
+ h[k] = []
1570
+ Thread.new do
1571
+ t = Process.detach(k)
1572
+ list = h[k]
1573
+ t.join
1574
+ h[k] = nil
1575
+ list.each do |e|
1576
+ e.call
1577
+ end
1578
+ end
1579
+ }
1580
+ if @@datachList[pid] != nil
1581
+ @@datachList[pid].push bl
1582
+ end
1583
+ end
1584
+
1585
+
1586
+ class Object
1587
+ def instanceVariableSet (k, v)
1588
+ first = true
1589
+ key = "@"
1590
+ k.split("_").each do |e|
1591
+ if first
1592
+ e.downcase!
1593
+ first = false
1594
+ else
1595
+ e.capitalize!
1596
+ end
1597
+ key += e
1598
+ end
1599
+ instance_variable_set(key, v)
1600
+ end
1601
+ end
1602
+
1603
+
1604
+
1605
+ class String
1606
+ def lspaces
1607
+ self =~ /^\s*/
1608
+ $&
1609
+ end
1610
+ def rspaces
1611
+ self =~ /\s*$/
1612
+ $&
1613
+ end
1614
+ def rspaces_comment
1615
+ self =~ /\s*\#.*$|\s*$/
1616
+ $&
1617
+ end
1618
+ def example
1619
+ self
1620
+ end
1621
+ def escapeHTML
1622
+ require 'cgi'
1623
+ CGI.escapeHTML self
1624
+ end
1625
+ def escapeURL
1626
+ require 'cgi'
1627
+ CGI.escape self
1628
+ end
1629
+ end
1630
+
1631
+
1632
+ class Array
1633
+ def first_result &bl
1634
+ each do |e|
1635
+ res = bl.call e
1636
+ return res if res
1637
+ end
1638
+ nil
1639
+ end
1640
+ end
1641
+
1642
+
1643
+ class String
1644
+ def basename_of arg
1645
+ if self[- arg.size .. -1] == arg
1646
+ self[0 .. self.size - arg.size - 1]
1647
+ else
1648
+ nil
1649
+ end
1650
+ end
1651
+ end
1652
+
1653
+
1654
+
1655
+ def nil.example
1656
+ ""
1657
+ end
1658
+
1659
+ class Regexp
1660
+ def example
1661
+ s = to_s.gsub /\\s/, " "
1662
+ s.gsub! /\?\-\w+:/, ""
1663
+ s.gsub! /\\d/, "0"
1664
+ s.gsub! /\\n/, "\n"
1665
+ s.gsub! /\\r/, "\r"
1666
+ s.gsub! /\\(.)/, '\1'
1667
+ s.gsub! /\(/, ""
1668
+ s.gsub! /\)/, ""
1669
+ s.gsub! "$", ""
1670
+ s.gsub! "^", ""
1671
+ s.gsub! /.\*/, ""
1672
+ s.gsub! /(.)\+/, '\1'
1673
+ s
1674
+ end
1675
+ end
1676
+
1677
+ def waitUntil t, step = 1
1678
+ cnt = t
1679
+ while !yield t - cnt
1680
+ if cnt == 0
1681
+ return false
1682
+ end
1683
+ sleep step
1684
+ cnt -= 1
1685
+ end
1686
+ return true
1687
+ end
1688
+
1689
+ require 'set'
1690
+
1691
+ def genpasswd sz = 12, str = "abcdefghijkmnpqrstuvwxyABCDERFHJKMNPQRSTUVWXY3456789!#$%&`()=~{}*+@_?/><"
1692
+ r = ""
1693
+ sz.times do
1694
+ r += str[rand(str.size)]
1695
+ end
1696
+ r
1697
+ end
1698
+ def genpassword *args
1699
+ genpasswd
1700
+ end
1701
+
1702
+
1703
+ module ProcWithArguments
1704
+ refine Symbol do
1705
+ def [] *bin_args
1706
+ proc do |*args|
1707
+ obj = args.shift
1708
+ obj.method(self).curry[*bin_args, *args]
1709
+ end
1710
+ end
1711
+ end
1712
+ end
1713
+
1714
+
1715
+ # "/etc/asdf".¿[:_e?]&.
1716
+