net-irc2 0.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
|