Added Riece pkg subtree
[packages] / xemacs-packages / riece / lisp / aproxy.rb
diff --git a/xemacs-packages/riece/lisp/aproxy.rb b/xemacs-packages/riece/lisp/aproxy.rb
new file mode 100644 (file)
index 0000000..90c80ba
--- /dev/null
@@ -0,0 +1,107 @@
+# aproxy.rb --- async proxy between an IRC server and a client
+# Copyright (C) 1998-2005 Daiki Ueno
+
+# Author: Daiki Ueno <ueno@unixuser.org>
+# Created: 1998-09-28
+# Keywords: IRC, riece
+
+# This file is part of Riece.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GNU Emacs; see the file COPYING.  If not, write to the
+# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+
+require 'io/nonblock'
+require 'socket'
+
+class AProxy
+  def initialize(host, port, size, back)
+    @host = host
+    @port = port
+    @size = size
+    @back = File.new(back, 'a') if back
+  end
+
+  def start
+    $stdout.nonblock = true
+    trap('STOP', 'IGNORE')
+    trap('TSTP', 'IGNORE')
+    socket = TCPSocket.new(@host, @port)
+    $stdout.write("NOTICE CONNECTED #{$$}\r\n")
+    wfds_in = []
+    buf = ''
+    loop do
+      rfds, wfds, = select([socket, $stdin], wfds_in)
+      unless wfds.empty?
+        if buf.length > @size
+          s = buf.slice!(0 ... @size)
+          @back.write(s) if @back
+        end
+        begin
+          until buf.empty?
+            len = $stdout.syswrite(buf)
+            buf.slice!(0 .. len)
+          end
+          wfds_in.clear
+        rescue Errno::EAGAIN
+        end
+      end
+      if rfds.include?(socket)
+        line = socket.gets("\r\n")
+        break unless line
+        if line =~ /\A(?::\S+\s+)?PING\s+(.*)\r\n/i
+          socket.write("PONG #{$1}\r\n")
+        else
+          wfds_in = [$stdout]
+          buf << line
+        end
+      end
+      if rfds.include?($stdin)
+        line = $stdin.gets("\r\n")
+        break unless line
+        socket.write(line)
+      end
+    end
+    socket.close
+  end
+end
+
+if $0 == __FILE__
+  require 'optparse'
+
+  opt_size, opt_back = nil, nil
+  opts = OptionParser.new do |opts|
+    opts.banner = <<"End"
+Usage: #{$0} [OPTIONS] host port
+End
+    opts.on('-s', '--size SIZE', 'Size of buffer.') do |size|
+      opt_size = size.to_i
+    end
+    opts.on('-b', '--back BACK', 'Send outdated messages to BACK.') do |back|
+      opt_back = back
+    end
+    opts.on_tail('--help', '-h', 'Show this message.') do
+      $stdout.print(opts.to_s)
+      exit(0)
+    end
+  end
+  begin
+    opts.parse!(ARGV)
+  rescue OptionParser::ParseError
+    $stderr.print(opts.to_s)
+    exit(1)
+  end
+
+  AProxy.new(ARGV.shift, ARGV.shift, opt_size, opt_back).start
+end