1 # A simple IPC server executing Ruby programs.
7 def initialize(outfile, errfile, logfile)
10 $stdout = outfile ? File.new(outfile, 'a') : StringIO.new
11 $stderr = errfile ? File.new(errfile, 'a') : StringIO.new
12 @log = File.new(logfile, 'a') if logfile
21 @log.puts(line) if @log
28 d = "dispatch_#{c.downcase}"
29 if respond_to?(d, true)
34 send_line("ERR 103 Unknown command\r\n")
39 def dispatch_cancel(c, r)
40 send_line("ERR 100 Not implemented\r\n")
43 def dispatch_bye(c, r)
44 send_line("ERR 100 Not implemented\r\n")
47 def dispatch_auth(c, r)
48 send_line("ERR 100 Not implemented\r\n")
51 def dispatch_reset(c, r)
52 send_line("ERR 100 Not implemented\r\n")
55 def dispatch_end(c, r)
59 def dispatch_help(c, r)
60 send_line("ERR 100 Not implemented\r\n")
63 def dispatch_quit(c, r)
64 send_line("ERR 100 Not implemented\r\n")
67 def dispatch_eval(c, r)
68 r = deq_data if r.empty?
71 while @thr.include?(name = @cnt.to_s)
74 @thr[name] = Thread.current
76 send_line("S name #{name}\r\n")
78 Thread.current[:rubyserv_name] = name
86 @log.puts(line) if @log
88 module_function :send_line
91 send_line("# output #{Thread.current[:rubyserv_name]} #{s}\r\n")
93 module_function :output
96 Thread.current[:rubyserv_error] = false
97 Thread.current[:rubyserv_response] = eval(r, env.module_eval {binding()})
99 Thread.current[:rubyserv_error] = true
100 Thread.current[:rubyserv_response] = e.to_s.sub(/\A.*?\n/, '')
102 send_line("# exit #{name}\r\n")
105 def dispatch_poll(c, r)
108 send_line("ERR 105 Parameter error: no such name \"#{r}\"\r\n")
110 send_line("S running #{r}\r\n")
113 if thr[:rubyserv_error]
114 send_line("S exited #{r}\r\n")
116 send_line("S finished #{r}\r\n")
118 if d = thr[:rubyserv_response]
125 def dispatch_exit(c, r)
128 send_line("ERR 105 Parameter error: no such name \"#{r}\"\r\n")
131 thr.kill if thr.alive?
137 s.gsub(/[%\r\n]/) {|m| '%%%02X' % m[0]}
141 s.gsub(/%([0-9A-Z][0-9A-Z])/) {[$1].pack('H*')}
147 len = [d.length, 998].min # 998 = 1000 - "D "
148 send_line("D #{d[0 ... len]}\r\n")
165 @log.puts(line) if @log
172 opt_outfile, opt_errfile, opt_logfile = nil, nil, nil
173 opts = OptionParser.new do |opts|
174 opts.banner = <<"End"
175 Usage: #{$0} [OPTIONS]
177 opts.on('-o', '--out OUTFILE', 'Send stdout to OUTFILE.') do |outfile|
178 opt_outfile = outfile
180 opts.on('-e', '--err ERRFILE', 'Send stderr to ERRFILE.') do |errfile|
181 opt_errfile = errfile
183 opts.on('-e', '--log LOGFILE', 'Send stdlog to LOGFILE.') do |logfile|
184 opt_logfile = logfile
186 opts.on_tail('--help', '-h', 'Show this message.') do
187 $stdout.print(opts.to_s)
193 rescue OptionParser::ParseError
194 $stderr.print(opts.to_s)
198 server = Server.new(opt_outfile, opt_errfile, opt_logfile)