From: ueno Date: Tue, 22 Mar 2005 08:57:10 +0000 (+0000) Subject: * rubyserv.rb: New file. X-Git-Tag: channel-coding-mergepoint~29 X-Git-Url: http://git.chise.org/gitweb/?a=commitdiff_plain;h=a11925d98327d96749937b697d801e853435a96a;p=elisp%2Friece.git * rubyserv.rb: New file. --- diff --git a/lisp/ChangeLog b/lisp/ChangeLog index be8b40d..7036259 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,7 @@ +2005-03-22 Daiki Ueno + + * rubyserv.rb: New file. + 2005-03-20 Daiki Ueno * riece-toolbar.el [XEmacs] (riece-make-toolbar-from-menu): diff --git a/lisp/rubyserv.rb b/lisp/rubyserv.rb new file mode 100644 index 0000000..d3a82ff --- /dev/null +++ b/lisp/rubyserv.rb @@ -0,0 +1,112 @@ +# A simple IPC server for executing arbitrary Ruby program. +# The protocol is based on Assuan protocol of GnuPG. + +require 'thread' +require 'stringio' + +class RubyServ + def initialize + @buf = StringIO.new + @que = Queue.new + end + + def dispatch(line) + case line.chomp + when /\AD / + return @buf << unescape($') + when /\A(\S+)\s*/ + c = $1 + r = $' + d = "dispatch_#{c.downcase}" + if respond_to?(d, true) + Thread.start do + self.send(d, c, r) + end + else + puts("ERR 103 Unknown command\r\n") + end + end + end + + def dispatch_cancel(c, r) + puts("ERR 100 Not implemented\r\n") + end + + def dispatch_bye(c, r) + puts("ERR 100 Not implemented\r\n") + end + + def dispatch_auth(c, r) + puts("ERR 100 Not implemented\r\n") + end + + def dispatch_reset(c, r) + puts("ERR 100 Not implemented\r\n") + end + + def dispatch_end(c, r) + enq_data + end + + def dispatch_help(c, r) + puts("ERR 100 Not implemented\r\n") + end + + def dispatch_quit(c, r) + puts("ERR 100 Not implemented\r\n") + end + + def dispatch_eval(c, r) + r = deq_data if r.empty? + p r + open('|-') do |f| + if f + d = f.read + Process.wait + send_data(d) + if $?.success? + puts("OK\r\n") + else + puts("ERR #{$?.exitstatus}\r\n") + end + else + eval(r) + exit + end + end + end + + def escape(s) + s.gsub(/[%\r\n]/) {|m| '%%%02X' % m[0]} + end + + def unescape(s) + s.gsub(/%([0-9A-Z][0-9A-Z])/, ['\1'].pack('H*')) + end + + def send_data(d) + begin + r = [d.length, 998].min # 998 = 1000 - CRLF + (0 ... r).each do |i| + r -= 2 if d[i] =~ /[%\r\n]/ + end + puts("D #{escape(d[0 ... r])}\r\n") + d = d[r .. -1] + end until d.empty? + end + + def enq_data + @que.enq(@buf.string) + end + + def deq_data + @que.deq + end +end + +if $0 == __FILE__ + serv = RubyServ.new + while gets + serv.dispatch($_) + end +end