-
Notifications
You must be signed in to change notification settings - Fork 1
/
interact.rb
executable file
·121 lines (113 loc) · 2.54 KB
/
interact.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#!/usr/bin/env ruby
# -*- encoding: utf-8
require 'readline'
require './eval'
require './client'
require './commands'
autocomplete = false
cli = Client.new *ARGV
eb = binding
Readline.completion_proc = lambda do |word|
return unless autocomplete
result = []
orgword = word
word ||= ""
scan = word.scan %r{(.*/)([^/]*)}
if scan.nil? or scan.empty?
orgprefix, orgsuffix = "", word
else
orgprefix, orgsuffix = scan.first
end
orgprefix ||= ""
orgsuffix ||= ""
word = nil if word.empty?
begin
Commands::Ls.new(nil).run(cli, word) { |r| result << r }
rescue Errno::ENOENT
if word.end_with? '/'
word.sub(%r{/$}, '')
elsif word['/']
word = word.sub(%r{/[^/]*$}, '/')
retry
else
word = nil
retry
end
end
result.map(&:first).select{|x| orgword.nil? or x.start_with?(orgsuffix)}.map{|x| orgprefix + x}
end
def sysexec(c,d)
old = `stty -g`
child = fork do
cli = c.dup
cli.call! Syscalls::NR_dup2, 3, 0
cli.call! Syscalls::NR_dup2, 3, 1
cli.call! Syscalls::NR_dup2, 3, 2
fd = cli.execve "/bin/sh", ["sh", "-c", d]
system "stty -icanon min 1 time 0 -echo"
rs = [fd]
while not fd.eof?
fd.close_write if STDIN.eof?
p rs
if rs.include? STDIN
buf = STDIN.readpartial(512)
fd << buf
elsif rs.include? fd
buf = fd.readpartial(512)
STDOUT << buf
end
rs, ws, es = IO.select([fd, STDIN], [], [fd], 1)
break unless es.empty?
end
end
Process.wait child
system "stty #{old}"
end
ev = Eval.new cli
puts "Server (version = #{cli.version}) is ready."
puts "Type :help for help."
def help
puts "Help"
puts " :help this help"
puts " :<ruby code> eval ruby code"
puts " :autocomplete={true|false} enable/disable tab filename autocompletion"
puts
puts "Commands"
Commands.constants.each do |cmdname|
cmd = Commands.const_get cmdname
cmdname = cmdname.to_s.downcase
init = cmd.instance_method(:initialize)
parms = []
parms = init.parameters if init.respond_to? :parameters
parms.shift
parms.map! do |t,n|
if t == :req
n
elsif t == :opt
"[#{n}]"
elsif t == :rest
"#{n}…"
else
"<#{n}>"
end
end
puts " #{cmdname} #{parms.join(' ')}"
end
""
end
while d = Readline.readline("(#{cli.pid})> ")
d.strip!
next if d.empty?
Readline::HISTORY.push d
if d =~ /^:/
p eval d[1..-1], eb
next
end
begin
ev.run d
rescue ArgumentError => e
STDERR << e << "\n"
rescue KeyError
STDERR << "Bad command or file name" << "\n"
end
end