#!/usr/bin/evn ruby require "optparse" opts = { :Port => 6667, :BindAddress => nil, :Log => File.expand_path('./log'), } hostname = nil version = nil OptionParser.new do |parser| parser.instance_eval do self.banner = <<-EOB.gsub(/^\t+/, "") Usage: #{$0} [opts] host_name version EOB separator "Options:" on("-p", "--port [PORT=#{opts[:Port]}]", "port number to listen") {|port| opts[:Port] = port } on("-h", "--host [HOST=#{opts[:host]}]", "host name or IP address to listen") {|host| opts[:BindAddress] = host } on("-l", "--log [LOG_DIR=#{opts[:Log]}]", "log directory") {|log| opts[:Log] = File.expand_path(log) } on("-v", "--verbose") { $verbose = true } parse!(ARGV) unless ARGV.length == 2 puts to_s exit 1 end hostname = ARGV.shift version = ARGV.shift end end # check log directory begin Dir.open(opts[:Log]) {|dir| } rescue puts "Log directory #{opts[:Log]} does not exist" exit 1 end $logdir = opts.delete(:Log) TIMEFORMAT = "%b %d %X" require 'thread' require 'ircd' require 'ircclient' $config ||= {} $config['port'] = opts[:Port] $config['hostname'] = hostname $config['version'] = version class HostActor < IrcClient::IrcActor def initialize(client) super(client) @channels = SynchronizedStore.new on(:join) {|nick,channel| @channels[channel] ||= File.open( File.join($logdir, channel), 'a' ) } on(:part) {|nick,channel,msg| } on(:privmsg) {|nick,channel,msg| if log = @channels[channel] log.puts "#{Time.now.strftime(TIMEFORMAT)}:#{nick}:#{channel}:#{msg}" log.flush end } end end class FlexIRCClient < IRCClient def handle_unknown(s) if s.include?("") reply :raw, %[\0] end carp "unknown:>#{s}<" reply :numeric, ERR_UNKNOWNCOMMAND,s, "Unknown command" end def raw(arg, abrt=false) begin carp "--> #{arg}" @socket.print arg.chomp + "\r\n" if !arg.nil? rescue Exception => e carp "<#{self.userprefix}>#{e.message}" #puts e.backtrace.join("\n") handle_abort() raise e if abrt end end end class FlexIRCServer < IRCServer def run(sock) client = FlexIRCClient.new(sock, self) client.handle_connect irc_listen(sock, client) end end server = FlexIRCServer.new( :Port => $config['port'] ) $host = ProxyClient.new(hostname, HostActor, server) class ParttyChannel < IRCChannel def initialize(name) super(name) join($host) end end class << $channel_store def add(c) self[c] ||= ParttyChannel.new(c) end end #begin trap("INT"){ server.carp "killing #{$$}" system("kill -9 #{$$}") server.shutdown } p = Thread.new { server.do_ping() } #server.addservice('partty.org', CentralActor) server.start #p.join #rescue Exception => e # server.carp e #end