net-irc2 0.0.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/AUTHORS.txt +33 -0
- data/ChangeLog +95 -0
- data/README +91 -0
- data/Rakefile +69 -0
- data/examples/2ch.rb +225 -0
- data/examples/2ig.rb +267 -0
- data/examples/client.rb +23 -0
- data/examples/echo_bot.rb +31 -0
- data/examples/echo_bot_celluloid.rb +33 -0
- data/examples/gig.rb +192 -0
- data/examples/gmail.rb +202 -0
- data/examples/gtig.rb +420 -0
- data/examples/hatena-star-stream.rb +270 -0
- data/examples/hcig.rb +285 -0
- data/examples/hig.rb +771 -0
- data/examples/iig.rb +819 -0
- data/examples/ircd.rb +358 -0
- data/examples/lig.rb +551 -0
- data/examples/lingr.rb +327 -0
- data/examples/mixi.rb +252 -0
- data/examples/sig.rb +188 -0
- data/examples/tig.rb +2712 -0
- data/lib/net/irc/client/channel_manager.rb +144 -0
- data/lib/net/irc/client.rb +117 -0
- data/lib/net/irc/constants.rb +214 -0
- data/lib/net/irc/message/modeparser.rb +85 -0
- data/lib/net/irc/message/serverconfig.rb +30 -0
- data/lib/net/irc/message.rb +109 -0
- data/lib/net/irc/pattern.rb +68 -0
- data/lib/net/irc/server.rb +186 -0
- data/lib/net/irc.rb +77 -0
- data/spec/channel_manager_spec.rb +184 -0
- data/spec/modeparser_spec.rb +165 -0
- data/spec/net-irc_spec.rb +337 -0
- data/spec/spec.opts +1 -0
- metadata +91 -0
data/examples/2ig.rb
ADDED
@@ -0,0 +1,267 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# vim:encoding=UTF-8:
|
3
|
+
|
4
|
+
$LOAD_PATH << "lib"
|
5
|
+
$LOAD_PATH << "../lib"
|
6
|
+
|
7
|
+
$KCODE = "u" if RUBY_VERSION < "1.9" # json use this
|
8
|
+
|
9
|
+
require "rubygems"
|
10
|
+
require "net/irc"
|
11
|
+
require "logger"
|
12
|
+
require "pathname"
|
13
|
+
require "yaml"
|
14
|
+
require 'uri'
|
15
|
+
require 'net/http'
|
16
|
+
require 'nkf'
|
17
|
+
require 'stringio'
|
18
|
+
require 'zlib'
|
19
|
+
|
20
|
+
require "#{Pathname.new(__FILE__).parent.expand_path}/2ch.rb"
|
21
|
+
Net::HTTP.version_1_2
|
22
|
+
|
23
|
+
class NiChannelIrcGateway < Net::IRC::Server::Session
|
24
|
+
def server_name
|
25
|
+
"2ch"
|
26
|
+
end
|
27
|
+
|
28
|
+
def server_version
|
29
|
+
"0.0.0"
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
def initialize(*args)
|
34
|
+
super
|
35
|
+
@channels = {}
|
36
|
+
end
|
37
|
+
|
38
|
+
def on_disconnected
|
39
|
+
@channels.each do |chan, info|
|
40
|
+
begin
|
41
|
+
info[:observer].kill if info[:observer]
|
42
|
+
rescue
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def on_user(m)
|
48
|
+
super
|
49
|
+
@real, *@opts = @real.split(/\s+/)
|
50
|
+
@opts ||= []
|
51
|
+
end
|
52
|
+
|
53
|
+
def on_join(m)
|
54
|
+
channels = m.params.first.split(/,/)
|
55
|
+
channels.each do |channel|
|
56
|
+
@channels[channel] = {
|
57
|
+
:topic => "",
|
58
|
+
:dat => nil,
|
59
|
+
:interval => nil,
|
60
|
+
:observer => nil,
|
61
|
+
} unless @channels.key?(channel)
|
62
|
+
post @prefix, JOIN, channel
|
63
|
+
post nil, RPL_NAMREPLY, @prefix.nick, "=", channel, "@#{@prefix.nick}"
|
64
|
+
post nil, RPL_ENDOFNAMES, @prefix.nick, channel, "End of NAMES list"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def on_part(m)
|
69
|
+
channel = m.params[0]
|
70
|
+
if @channels.key?(channel)
|
71
|
+
info = @channels.delete(channel)
|
72
|
+
info[:observer].kill if info[:observer]
|
73
|
+
post @prefix, PART, channel
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def on_privmsg(m)
|
78
|
+
target, mesg = *m.params
|
79
|
+
m.ctcps.each {|ctcp| on_ctcp(target, ctcp) } if m.ctcp?
|
80
|
+
end
|
81
|
+
|
82
|
+
def on_ctcp(target, mesg)
|
83
|
+
type, mesg = mesg.split(" ", 2)
|
84
|
+
method = "on_ctcp_#{type.downcase}".to_sym
|
85
|
+
send(method, target, mesg) if respond_to? method, true
|
86
|
+
end
|
87
|
+
|
88
|
+
def on_ctcp_action(target, mesg)
|
89
|
+
command, *args = mesg.split(" ")
|
90
|
+
command.downcase!
|
91
|
+
|
92
|
+
case command
|
93
|
+
when 'next'
|
94
|
+
if @channels.key?(target)
|
95
|
+
guess_next_thread(target)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
rescue Exception => e
|
99
|
+
@log.error e.inspect
|
100
|
+
e.backtrace.each do |l|
|
101
|
+
@log.error "\t#{l}"
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def on_topic(m)
|
106
|
+
channel, topic, = m.params
|
107
|
+
p m.params
|
108
|
+
if @channels.key?(channel)
|
109
|
+
info = @channels[channel]
|
110
|
+
|
111
|
+
unless topic
|
112
|
+
post nil, '332', channel, info[:topic]
|
113
|
+
return
|
114
|
+
end
|
115
|
+
|
116
|
+
uri, interval = *topic.split(/\s/)
|
117
|
+
interval = interval.to_i
|
118
|
+
|
119
|
+
post @prefix, TOPIC, channel, topic
|
120
|
+
|
121
|
+
case
|
122
|
+
when !info[:dat], uri != info[:dat].uri
|
123
|
+
post @prefix, NOTICE, channel, "Thread URL has been changed."
|
124
|
+
info[:dat] = ThreadData.new(uri)
|
125
|
+
create_observer(channel)
|
126
|
+
when info[:interval] != interval
|
127
|
+
post @prefix, NOTICE, channel, "Interval has been changed."
|
128
|
+
create_observer(channel)
|
129
|
+
end
|
130
|
+
info[:topic] = topic
|
131
|
+
info[:interval] = interval > 0 ? interval : 90
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def guess_next_thread(channel)
|
136
|
+
info = @channels[channel]
|
137
|
+
post server_name, NOTICE, channel, "Current Thread: #{info[:dat].subject}"
|
138
|
+
threads = info[:dat].guess_next_thread
|
139
|
+
threads.first(3).each do |t|
|
140
|
+
if t[:continuous_num] && t[:appear_recent]
|
141
|
+
post server_name, NOTICE, channel, "#{t[:uri]} \003%d#{t[:subject]}\017" % 10
|
142
|
+
else
|
143
|
+
post server_name, NOTICE, channel, "#{t[:uri]} #{t[:subject]}"
|
144
|
+
end
|
145
|
+
end
|
146
|
+
threads
|
147
|
+
end
|
148
|
+
|
149
|
+
def create_observer(channel)
|
150
|
+
info = @channels[channel]
|
151
|
+
info[:observer].kill if info[:observer]
|
152
|
+
|
153
|
+
@log.debug "create_observer %s, interval %d" % [channel, info[:interval].to_i]
|
154
|
+
info[:observer] = Thread.start(info, channel) do |info, channel|
|
155
|
+
Thread.pass
|
156
|
+
|
157
|
+
loop do
|
158
|
+
begin
|
159
|
+
sleep info[:interval]
|
160
|
+
@log.debug "retrieving (interval %d) %s..." % [info[:interval], info[:dat].uri]
|
161
|
+
info[:dat].retrieve.last(100).each do |line|
|
162
|
+
priv_line channel, line
|
163
|
+
end
|
164
|
+
|
165
|
+
if info[:dat].length >= 1000
|
166
|
+
post server_name, NOTICE, channel, "Thread is over 1000. Guessing next thread..."
|
167
|
+
guess_next_thread(channel)
|
168
|
+
break
|
169
|
+
end
|
170
|
+
rescue UnknownThread
|
171
|
+
# pass
|
172
|
+
rescue Exception => e
|
173
|
+
@log.error "Error: #{e.inspect}"
|
174
|
+
e.backtrace.each do |l|
|
175
|
+
@log.error "\t#{l}"
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
def priv_line(channel, line)
|
183
|
+
post "%d{%s}" % [line.n, line.id], PRIVMSG, channel, line.aa?? encode_aa(line.body) : line.body
|
184
|
+
end
|
185
|
+
|
186
|
+
def encode_aa(aa)
|
187
|
+
uri = URI('http://tinyurl.com/api-create.php')
|
188
|
+
uri.query = 'url=' + URI.escape(<<-EOS.gsub(/[\n\t]/, ''))
|
189
|
+
data:text/html,<pre style='font-family:"IPA モナー Pゴシック"'>#{aa.gsub(/\n/, '<br>')}</pre>
|
190
|
+
EOS
|
191
|
+
Net::HTTP.get(uri.host, uri.request_uri, uri.port)
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
if __FILE__ == $0
|
196
|
+
require "optparse"
|
197
|
+
|
198
|
+
opts = {
|
199
|
+
:port => 16701,
|
200
|
+
:host => "localhost",
|
201
|
+
:log => nil,
|
202
|
+
:debug => false,
|
203
|
+
:foreground => false,
|
204
|
+
}
|
205
|
+
|
206
|
+
OptionParser.new do |parser|
|
207
|
+
parser.instance_eval do
|
208
|
+
self.banner = <<-EOB.gsub(/^\t+/, "")
|
209
|
+
Usage: #{$0} [opts]
|
210
|
+
|
211
|
+
EOB
|
212
|
+
|
213
|
+
separator ""
|
214
|
+
|
215
|
+
separator "Options:"
|
216
|
+
on("-p", "--port [PORT=#{opts[:port]}]", "port number to listen") do |port|
|
217
|
+
opts[:port] = port
|
218
|
+
end
|
219
|
+
|
220
|
+
on("-h", "--host [HOST=#{opts[:host]}]", "host name or IP address to listen") do |host|
|
221
|
+
opts[:host] = host
|
222
|
+
end
|
223
|
+
|
224
|
+
on("-l", "--log LOG", "log file") do |log|
|
225
|
+
opts[:log] = log
|
226
|
+
end
|
227
|
+
|
228
|
+
on("--debug", "Enable debug mode") do |debug|
|
229
|
+
opts[:log] = $stdout
|
230
|
+
opts[:debug] = true
|
231
|
+
end
|
232
|
+
|
233
|
+
on("-f", "--foreground", "run foreground") do |foreground|
|
234
|
+
opts[:log] = $stdout
|
235
|
+
opts[:foreground] = true
|
236
|
+
end
|
237
|
+
|
238
|
+
parse!(ARGV)
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
opts[:logger] = Logger.new(opts[:log], "daily")
|
243
|
+
opts[:logger].level = opts[:debug] ? Logger::DEBUG : Logger::INFO
|
244
|
+
|
245
|
+
def daemonize(foreground=false)
|
246
|
+
trap("SIGINT") { exit! 0 }
|
247
|
+
trap("SIGTERM") { exit! 0 }
|
248
|
+
trap("SIGHUP") { exit! 0 }
|
249
|
+
return yield if $DEBUG || foreground
|
250
|
+
Process.fork do
|
251
|
+
Process.setsid
|
252
|
+
Dir.chdir "/"
|
253
|
+
File.open("/dev/null") {|f|
|
254
|
+
STDIN.reopen f
|
255
|
+
STDOUT.reopen f
|
256
|
+
STDERR.reopen f
|
257
|
+
}
|
258
|
+
yield
|
259
|
+
end
|
260
|
+
exit! 0
|
261
|
+
end
|
262
|
+
|
263
|
+
daemonize(opts[:debug] || opts[:foreground]) do
|
264
|
+
Net::IRC::Server.new(opts[:host], opts[:port], NiChannelIrcGateway, opts).start
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
data/examples/client.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# vim:fileencoding=UTF-8:
|
3
|
+
|
4
|
+
$LOAD_PATH << "lib"
|
5
|
+
$LOAD_PATH << "../lib"
|
6
|
+
|
7
|
+
require "rubygems"
|
8
|
+
require "net/irc"
|
9
|
+
|
10
|
+
require "pp"
|
11
|
+
|
12
|
+
class SimpleClient < Net::IRC::Client
|
13
|
+
def initialize(*args)
|
14
|
+
super
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
SimpleClient.new("foobar", "6667", {
|
19
|
+
:nick => "foobartest",
|
20
|
+
:user => "foobartest",
|
21
|
+
:real => "foobartest",
|
22
|
+
}).start
|
23
|
+
|
@@ -0,0 +1,31 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# vim:encoding=UTF-8:
|
3
|
+
|
4
|
+
$LOAD_PATH << "lib"
|
5
|
+
$LOAD_PATH << "../lib"
|
6
|
+
|
7
|
+
require "rubygems"
|
8
|
+
require "net/irc"
|
9
|
+
|
10
|
+
require "pp"
|
11
|
+
|
12
|
+
class EchoBot < Net::IRC::Client
|
13
|
+
def initialize(*args)
|
14
|
+
super
|
15
|
+
end
|
16
|
+
|
17
|
+
def on_rpl_welcome(m)
|
18
|
+
post JOIN, "#bot_test"
|
19
|
+
end
|
20
|
+
|
21
|
+
def on_privmsg(m)
|
22
|
+
post NOTICE, m[0], m[1]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
EchoBot.new("foobar", "6667", {
|
27
|
+
:nick => "foobartest",
|
28
|
+
:user => "foobartest",
|
29
|
+
:real => "foobartest",
|
30
|
+
}).start
|
31
|
+
|
@@ -0,0 +1,33 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# vim:encoding=UTF-8:
|
3
|
+
|
4
|
+
$LOAD_PATH << "lib"
|
5
|
+
$LOAD_PATH << "../lib"
|
6
|
+
|
7
|
+
require "rubygems"
|
8
|
+
require "net/irc"
|
9
|
+
|
10
|
+
require "pp"
|
11
|
+
|
12
|
+
require 'celluloid/io'
|
13
|
+
|
14
|
+
class EchoBot < Net::IRC::Client
|
15
|
+
include Celluloid::IO
|
16
|
+
def on_rpl_welcome(m)
|
17
|
+
post JOIN, "#demo"
|
18
|
+
super
|
19
|
+
end
|
20
|
+
|
21
|
+
def on_privmsg(m)
|
22
|
+
post NOTICE, m[0], m[1]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
supervisor = EchoBot.supervise_as :echo_bot, "127.0.0.1", "6667", {
|
28
|
+
:nick => "foo",
|
29
|
+
:user => "foo",
|
30
|
+
:real => "foobartest",
|
31
|
+
}
|
32
|
+
supervisor.actor.start!
|
33
|
+
sleep
|
data/examples/gig.rb
ADDED
@@ -0,0 +1,192 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# vim:encoding=UTF-8:
|
3
|
+
=begin
|
4
|
+
# gig.rb
|
5
|
+
|
6
|
+
Github IRC Gateway
|
7
|
+
|
8
|
+
=end
|
9
|
+
|
10
|
+
$LOAD_PATH << "lib"
|
11
|
+
$LOAD_PATH << "../lib"
|
12
|
+
|
13
|
+
$KCODE = "u" unless defined? ::Encoding
|
14
|
+
|
15
|
+
require "rubygems"
|
16
|
+
require "net/irc"
|
17
|
+
require "net/https"
|
18
|
+
require "logger"
|
19
|
+
require "pathname"
|
20
|
+
require "libxml"
|
21
|
+
require "ostruct"
|
22
|
+
require 'time'
|
23
|
+
|
24
|
+
class ServerLogIrcGateway < Net::IRC::Server::Session
|
25
|
+
EVENTS = {
|
26
|
+
'DownloadEvent' => '6',
|
27
|
+
'GistEvent' => '10',
|
28
|
+
'WatchEvent' => '15',
|
29
|
+
'FollowEvent' => '15',
|
30
|
+
'CreateEvent' => '13',
|
31
|
+
'ForkEvent' => '3',
|
32
|
+
'PushEvent' => '14',
|
33
|
+
}
|
34
|
+
|
35
|
+
def server_name
|
36
|
+
"github"
|
37
|
+
end
|
38
|
+
|
39
|
+
def server_version
|
40
|
+
"0.0.0"
|
41
|
+
end
|
42
|
+
|
43
|
+
def main_channel
|
44
|
+
@opts.main_channel || "#github"
|
45
|
+
end
|
46
|
+
|
47
|
+
def initialize(*args)
|
48
|
+
super
|
49
|
+
@last_retrieved = Time.now
|
50
|
+
@cert_store = OpenSSL::X509::Store.new
|
51
|
+
@cert_store.set_default_paths
|
52
|
+
end
|
53
|
+
|
54
|
+
def on_disconnected
|
55
|
+
@retrieve_thread.kill rescue nil
|
56
|
+
end
|
57
|
+
|
58
|
+
def on_user(m)
|
59
|
+
super
|
60
|
+
@real, *@opts = @real.split(/\s+/)
|
61
|
+
@opts = OpenStruct.new @opts.inject({}) {|r, i|
|
62
|
+
key, value = i.split("=", 2)
|
63
|
+
r.update key => case value
|
64
|
+
when nil then true
|
65
|
+
when /\A\d+\z/ then value.to_i
|
66
|
+
when /\A(?:\d+\.\d*|\.\d+)\z/ then value.to_f
|
67
|
+
else value
|
68
|
+
end
|
69
|
+
}
|
70
|
+
post @nick, JOIN, main_channel
|
71
|
+
|
72
|
+
@retrieve_thread = Thread.start do
|
73
|
+
loop do
|
74
|
+
begin
|
75
|
+
@log.info 'retrieveing feed...'
|
76
|
+
uri = URI.parse("https://github.com/#{@real}.private.atom?token=#{@pass}")
|
77
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
78
|
+
http.use_ssl = true
|
79
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
80
|
+
http.cert_store = @cert_store
|
81
|
+
req = Net::HTTP::Get.new(uri.request_uri)
|
82
|
+
res = http.request(req)
|
83
|
+
|
84
|
+
doc = LibXML::XML::Document.string(res.body, :base_uri => uri.to_s)
|
85
|
+
ns = %w|a:http://www.w3.org/2005/Atom|
|
86
|
+
entries = []
|
87
|
+
doc.find('/a:feed/a:entry', ns).each do |n|
|
88
|
+
entries << {
|
89
|
+
:datetime => Time.parse(n.find('string(a:published)', ns)),
|
90
|
+
:id => n.find('string(a:id)', ns),
|
91
|
+
:title => n.find('string(a:title)', ns),
|
92
|
+
:author => n.find('string(a:author/a:name)', ns),
|
93
|
+
:link => n.find('string(a:link/@href)', ns),
|
94
|
+
}
|
95
|
+
end
|
96
|
+
|
97
|
+
entries.reverse_each do |entry|
|
98
|
+
next if entry[:datetime] <= @last_retrieved
|
99
|
+
type = entry[:id][%r|tag:github.com,2008:(.+?)/\d+|, 1]
|
100
|
+
post entry[:author], PRIVMSG, main_channel,
|
101
|
+
"\003#{EVENTS[type] || '5'}#{entry[:title]}\017 \00314#{entry[:link]}\017"
|
102
|
+
end
|
103
|
+
|
104
|
+
@last_retrieved = entries.first[:datetime]
|
105
|
+
@log.info 'sleep'
|
106
|
+
sleep 30
|
107
|
+
rescue Exception => e
|
108
|
+
@log.error e.inspect
|
109
|
+
e.backtrace.each do |l|
|
110
|
+
@log.error "\t#{l}"
|
111
|
+
end
|
112
|
+
sleep 10
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
if __FILE__ == $0
|
120
|
+
require "optparse"
|
121
|
+
|
122
|
+
opts = {
|
123
|
+
:port => 16705,
|
124
|
+
:host => "localhost",
|
125
|
+
:log => nil,
|
126
|
+
:debug => false,
|
127
|
+
:foreground => false,
|
128
|
+
}
|
129
|
+
|
130
|
+
OptionParser.new do |parser|
|
131
|
+
parser.instance_eval do
|
132
|
+
self.banner = <<-EOB.gsub(/^\t+/, "")
|
133
|
+
Usage: #{$0} [opts]
|
134
|
+
|
135
|
+
EOB
|
136
|
+
|
137
|
+
separator ""
|
138
|
+
|
139
|
+
separator "Options:"
|
140
|
+
on("-p", "--port [PORT=#{opts[:port]}]", "port number to listen") do |port|
|
141
|
+
opts[:port] = port
|
142
|
+
end
|
143
|
+
|
144
|
+
on("-h", "--host [HOST=#{opts[:host]}]", "host name or IP address to listen") do |host|
|
145
|
+
opts[:host] = host
|
146
|
+
end
|
147
|
+
|
148
|
+
on("-l", "--log LOG", "log file") do |log|
|
149
|
+
opts[:log] = log
|
150
|
+
end
|
151
|
+
|
152
|
+
on("--debug", "Enable debug mode") do |debug|
|
153
|
+
opts[:log] = $stdout
|
154
|
+
opts[:debug] = true
|
155
|
+
end
|
156
|
+
|
157
|
+
on("-f", "--foreground", "run foreground") do |foreground|
|
158
|
+
opts[:log] = $stdout
|
159
|
+
opts[:foreground] = true
|
160
|
+
end
|
161
|
+
|
162
|
+
parse!(ARGV)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
opts[:logger] = Logger.new(opts[:log], "daily")
|
167
|
+
opts[:logger].level = opts[:debug] ? Logger::DEBUG : Logger::INFO
|
168
|
+
|
169
|
+
def daemonize(foreground=false)
|
170
|
+
trap("SIGINT") { exit! 0 }
|
171
|
+
trap("SIGTERM") { exit! 0 }
|
172
|
+
trap("SIGHUP") { exit! 0 }
|
173
|
+
return yield if $DEBUG || foreground
|
174
|
+
Process.fork do
|
175
|
+
Process.setsid
|
176
|
+
Dir.chdir "/"
|
177
|
+
File.open("/dev/null") {|f|
|
178
|
+
STDIN.reopen f
|
179
|
+
STDOUT.reopen f
|
180
|
+
STDERR.reopen f
|
181
|
+
}
|
182
|
+
yield
|
183
|
+
end
|
184
|
+
exit! 0
|
185
|
+
end
|
186
|
+
|
187
|
+
daemonize(opts[:debug] || opts[:foreground]) do
|
188
|
+
Net::IRC::Server.new(opts[:host], opts[:port], ServerLogIrcGateway, opts).start
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
|