failirc 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. data/bin/failbot +162 -0
  2. data/bin/failircd +61 -0
  3. data/lib/failirc.rb +25 -0
  4. data/lib/failirc/client.rb +227 -0
  5. data/lib/failirc/client/channel.rb +98 -0
  6. data/lib/failirc/client/channels.rb +85 -0
  7. data/lib/failirc/client/client.rb +59 -0
  8. data/lib/failirc/client/clients.rb +43 -0
  9. data/lib/failirc/client/dispatcher.rb +209 -0
  10. data/lib/failirc/client/dispatcher/connectiondispatcher.rb +410 -0
  11. data/lib/failirc/client/dispatcher/event.rb +113 -0
  12. data/lib/failirc/client/dispatcher/eventdispatcher.rb +203 -0
  13. data/lib/failirc/client/module.rb +103 -0
  14. data/lib/failirc/client/modules/Base.rb +361 -0
  15. data/lib/failirc/client/modules/Logger.rb +89 -0
  16. data/lib/failirc/client/server.rb +89 -0
  17. data/lib/failirc/client/user.rb +66 -0
  18. data/lib/failirc/client/users.rb +100 -0
  19. data/lib/failirc/errors.rb +339 -0
  20. data/lib/failirc/extensions.rb +124 -0
  21. data/lib/failirc/mask.rb +117 -0
  22. data/lib/failirc/modes.rb +54 -0
  23. data/lib/failirc/responses.rb +360 -0
  24. data/lib/failirc/server.rb +266 -0
  25. data/lib/failirc/server/channel.rb +122 -0
  26. data/lib/failirc/server/channels.rb +84 -0
  27. data/lib/failirc/server/client.rb +100 -0
  28. data/lib/failirc/server/clients.rb +54 -0
  29. data/lib/failirc/server/dispatcher.rb +219 -0
  30. data/lib/failirc/server/dispatcher/connectiondispatcher.rb +477 -0
  31. data/lib/failirc/server/dispatcher/event.rb +113 -0
  32. data/lib/failirc/server/dispatcher/eventdispatcher.rb +196 -0
  33. data/lib/failirc/server/link.rb +50 -0
  34. data/lib/failirc/server/links.rb +49 -0
  35. data/lib/failirc/server/module.rb +103 -0
  36. data/lib/failirc/server/modules/Base.rb +2545 -0
  37. data/lib/failirc/server/modules/Cloaking.rb +170 -0
  38. data/lib/failirc/server/modules/Firewall.rb +104 -0
  39. data/lib/failirc/server/modules/Netlog.rb +67 -0
  40. data/lib/failirc/server/modules/Roulette.rb +78 -0
  41. data/lib/failirc/server/modules/TinyURL.rb +98 -0
  42. data/lib/failirc/server/modules/Translate.rb +62 -0
  43. data/lib/failirc/server/modules/WordFilter.rb +144 -0
  44. data/lib/failirc/server/user.rb +72 -0
  45. data/lib/failirc/server/users.rb +103 -0
  46. data/lib/failirc/sslutils.rb +74 -0
  47. data/lib/failirc/utils.rb +53 -0
  48. metadata +107 -0
@@ -0,0 +1,162 @@
1
+ #! /usr/bin/env ruby
2
+ # failirc, a fail IRC server.
3
+ #
4
+ # Copyleft meh. [http://meh.doesntexist.org | meh.ffff@gmail.com]
5
+ #
6
+ # This file is part of failirc.
7
+ #
8
+ # failirc is free software: you can redistribute it and/or modify
9
+ # it under the terms of the GNU Affero General Public License as published
10
+ # by the Free Software Foundation, either version 3 of the License, or
11
+ # (at your option) any later version.
12
+ #
13
+ # failirc is distributed in the hope that it will be useful,
14
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ # GNU Affero General Public License for more details.
17
+ #
18
+ # You should have received a copy of the GNU Affero General Public License
19
+ # along with failirc. If not, see <http://www.gnu.org/licenses/>.
20
+
21
+ require 'failirc/client'
22
+ require 'getoptlong'
23
+ require 'uri'
24
+ require 'net/http'
25
+ require 'timeout'
26
+
27
+ args = GetoptLong.new(
28
+ ['--version', '-v', GetoptLong::NO_ARGUMENT],
29
+ ['--verbose', '-V', GetoptLong::NO_ARGUMENT],
30
+ ['--config', '-f', GetoptLong::REQUIRED_ARGUMENT]
31
+ )
32
+
33
+ options = {
34
+ :verbose => false,
35
+ :config => '/etc/failbot.conf',
36
+ }
37
+
38
+ args.each {|option, value|
39
+ case option
40
+
41
+ when '--version'
42
+ puts "Fail IRCd #{IRC::VERSION}"
43
+ exit 0
44
+
45
+ when '--verbose'
46
+ options[:verbose] = true
47
+
48
+ when '--config'
49
+ options[:config] = value
50
+
51
+ end
52
+ }
53
+
54
+ $client = IRC::Client.new(File.new(options[:config]), options[:verbose])
55
+
56
+ def stop (client)
57
+ client.stop
58
+ Process.exit!(0)
59
+ end
60
+
61
+ trap('INT') { stop $client }
62
+ trap('KILL') { stop $client }
63
+
64
+ $urls = {}
65
+
66
+ module Commands
67
+ def self.quit (server, from, to, string)
68
+ $client.servers.each_value {|server|
69
+ $client.execute :quit, server, string
70
+ }
71
+
72
+ self.debug 'Quitting...'
73
+
74
+ while true
75
+ if $client.servers.empty?
76
+ Process.exit!(0)
77
+ end
78
+
79
+ sleep 0.1
80
+ end
81
+ end
82
+
83
+ def self.echo (server, from, to, string)
84
+ if !to.is_a?(IRC::Client::Channel)
85
+ to = from
86
+ end
87
+
88
+ $client.execute :message, server, :output, $client, to, string
89
+ end
90
+
91
+ def self.say (server, from, to, string)
92
+ matches = string.match(/^(.+?) (.+)$/)
93
+
94
+ $client.execute :message, server, :output, $client, matches[1], matches[2]
95
+ end
96
+
97
+ def self.urls (server, from, to, string)
98
+ if !to.is_a?(IRC::Client::Channel)
99
+ to = from
100
+ end
101
+
102
+ $urls.each_value {|url|
103
+ $client.execute :message, server, :output, $client, to, "[#{url[:at]}] #{url[:uri]} { #{url[:from]} }"
104
+ }
105
+ end
106
+ end
107
+
108
+ # check for connection
109
+ $client.register :custom, :connected, lambda {|server|
110
+ $client.config.elements.each('config/misc/channels/channel') {|channel|
111
+ $client.execute :join, server, channel.text
112
+ }
113
+ }
114
+
115
+ # fetch URLs
116
+ $client.register :custom, :message, lambda {|server, chain, from, to, message|
117
+ if chain != :input
118
+ return
119
+ end
120
+
121
+ URI.extract(message).each {|uri|
122
+ if match = uri.match('http://tinyurl.com/(.+)$')
123
+ uri = timeout 5 do
124
+ Net::HTTP.get(URI.parse("http://preview.tinyurl.com/#{match[1]}"))
125
+ end rescue nil
126
+
127
+ if !uri
128
+ next
129
+ end
130
+
131
+ if match = uri.match(/redirecturl" href="(.+?)"/)
132
+ uri = URI.decode(match[1])
133
+ else
134
+ next
135
+ end
136
+ end
137
+
138
+ if $urls[uri]
139
+ next
140
+ end
141
+
142
+ $urls[uri] = {
143
+ :from => from.mask.to_s,
144
+ :to => to.to_s,
145
+ :uri => uri,
146
+ :at => Time.now,
147
+ }
148
+ }
149
+ }
150
+
151
+ # dispatch commands
152
+ $client.register :custom, :message, lambda {|server, chain, from, to, message|
153
+ if chain != :input
154
+ return
155
+ end
156
+
157
+ if match = message.match(/^~([^ ]+)(\s+(.*))?$/)
158
+ Commands.method(match[1].to_sym).call(server, from, to, match[3])
159
+ end
160
+ }
161
+
162
+ $client.start
@@ -0,0 +1,61 @@
1
+ #! /usr/bin/env ruby
2
+ # failirc, a fail IRC server.
3
+ #
4
+ # Copyleft meh. [http://meh.doesntexist.org | meh.ffff@gmail.com]
5
+ #
6
+ # This file is part of failirc.
7
+ #
8
+ # failirc is free software: you can redistribute it and/or modify
9
+ # it under the terms of the GNU Affero General Public License as published
10
+ # by the Free Software Foundation, either version 3 of the License, or
11
+ # (at your option) any later version.
12
+ #
13
+ # failirc is distributed in the hope that it will be useful,
14
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ # GNU Affero General Public License for more details.
17
+ #
18
+ # You should have received a copy of the GNU Affero General Public License
19
+ # along with failirc. If not, see <http://www.gnu.org/licenses/>.
20
+
21
+ require 'failirc/server'
22
+ require 'getoptlong'
23
+
24
+ args = GetoptLong.new(
25
+ ['--version', '-v', GetoptLong::NO_ARGUMENT],
26
+ ['--verbose', '-V', GetoptLong::NO_ARGUMENT],
27
+ ['--config', '-f', GetoptLong::REQUIRED_ARGUMENT]
28
+ )
29
+
30
+ options = {
31
+ :verbose => false,
32
+ :config => '/etc/failircd.conf',
33
+ }
34
+
35
+ args.each {|option, value|
36
+ case option
37
+
38
+ when '--version'
39
+ puts "Fail IRCd #{IRC::VERSION}"
40
+ exit 0
41
+
42
+ when '--verbose'
43
+ options[:verbose] = true
44
+
45
+ when '--config'
46
+ options[:config] = value
47
+
48
+ end
49
+ }
50
+
51
+ ircd = IRC::Server.new(File.new(options[:config]), options[:verbose])
52
+
53
+ def stop (ircd)
54
+ ircd.stop
55
+ Process.exit!(0)
56
+ end
57
+
58
+ trap('INT') { stop ircd }
59
+ trap('KILL') { stop ircd }
60
+
61
+ ircd.start
@@ -0,0 +1,25 @@
1
+ # failirc, a fail IRC library.
2
+ #
3
+ # Copyleft meh. [http://meh.doesntexist.org | meh.ffff@gmail.com]
4
+ #
5
+ # This file is part of failirc.
6
+ #
7
+ # failirc is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU Affero General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # failirc is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU Affero General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Affero General Public License
18
+ # along with failirc. If not, see <http://www.gnu.org/licenses/>.
19
+
20
+ require 'failirc/server'
21
+ require 'failirc/client'
22
+
23
+ module IRC
24
+ VERSION = '0.0.1'
25
+ end
@@ -0,0 +1,227 @@
1
+ # failirc, a fail IRC library.
2
+ #
3
+ # Copyleft meh. [http://meh.doesntexist.org | meh.ffff@gmail.com]
4
+ #
5
+ # This file is part of failirc.
6
+ #
7
+ # failirc is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU Affero General Public License as published
9
+ # by the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # failirc is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU Affero General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU Affero General Public License
18
+ # along with failirc. If not, see <http://www.gnu.org/licenses/>.
19
+
20
+ require 'resolv'
21
+
22
+ require 'rexml/document'
23
+ include REXML
24
+
25
+ require 'failirc'
26
+ require 'failirc/utils'
27
+
28
+ require 'failirc/client/dispatcher'
29
+
30
+ require 'failirc/client/client'
31
+ require 'failirc/client/user'
32
+ require 'failirc/client/channel'
33
+
34
+ module IRC
35
+
36
+ class Client
37
+ attr_reader :version, :verbose, :config, :modules, :dispatcher
38
+
39
+ def initialize (conf, verbose)
40
+ @version = IRC::VERSION
41
+ @verbose = verbose
42
+
43
+ @modules = {}
44
+
45
+ @dispatcher = Dispatcher.new self
46
+
47
+ self.config = conf
48
+ end
49
+
50
+ def loadModule (name, path=nil, reload=false)
51
+ if @modules[name] && !reload
52
+ return
53
+ end
54
+
55
+ begin
56
+ if path[0] == '/'
57
+ $LOAD_PATH.push path
58
+ require name
59
+ $LOAD_PATH.pop
60
+ else
61
+ require "#{path}/#{name}"
62
+ end
63
+
64
+ klass = eval("Modules::#{name}") rescue nil
65
+
66
+ if klass
67
+ @modules[name] = klass.new(self)
68
+ self.debug "Loaded `#{name}`."
69
+ else
70
+ raise Exception
71
+ end
72
+ rescue Exception => e
73
+ self.debug "Failed to load `#{name}`."
74
+ self.debug e
75
+ end
76
+ end
77
+
78
+ def start
79
+ if @started
80
+ return
81
+ end
82
+
83
+ if !@config
84
+ raise 'config is missing'
85
+ end
86
+
87
+ @started = true
88
+
89
+ @config.elements.each('config/servers/server') {|element|
90
+ self.connect({
91
+ :host => element.attributes['host'],
92
+ :port => element.attributes['port'],
93
+
94
+ :ssl => element.attributes['ssl'],
95
+ :ssl_cert => element.attributes['sslCert'],
96
+ :ssl_key => element.attributes['sslKey']
97
+ }, element)
98
+ }
99
+
100
+ @dispatcher.start
101
+ end
102
+
103
+ def stop
104
+ @stopping = true
105
+
106
+ begin
107
+ dispatcher.stop
108
+
109
+ @modules.each {|mod|
110
+ mod.finalize
111
+ }
112
+ rescue
113
+ end
114
+
115
+ @stopping = false
116
+ @started = false
117
+ end
118
+
119
+ def connect (*args)
120
+ @dispatcher.connection.connect(*args)
121
+ end
122
+
123
+ def servers
124
+ dispatcher.servers[:byName]
125
+ end
126
+
127
+ def server (identifier)
128
+ dispatcher.server identifier
129
+ end
130
+
131
+ def alias (*args)
132
+ dispatcher.alias(*args)
133
+ end
134
+
135
+ def register (*args)
136
+ dispatcher.register(*args)
137
+ end
138
+
139
+ def nick
140
+ @config.elements['config/informations/nick'].text
141
+ end
142
+
143
+ def user
144
+ @config.elements['config/informations/user'].text
145
+ end
146
+
147
+ def realName
148
+ @config.elements['config/informations/realName'].text
149
+ end
150
+
151
+ def execute (*args)
152
+ @dispatcher.execute(*args)
153
+ end
154
+
155
+ def rehash
156
+ self.config = @configReference
157
+ end
158
+
159
+ def config= (reference)
160
+ if reference.is_a?(Hash)
161
+ @config = Document.new
162
+
163
+ @config.add Element.new 'config'
164
+ @config.elements['config'].add Element.new 'informations'
165
+ @config.elements['config'].add Element.new 'servers'
166
+ @config.elements['config'].add Element.new 'modules'
167
+
168
+ informations = @config.elements['config/informations']
169
+
170
+ informations.add(Element.new 'nick').text = reference[:nick] || 'fail'
171
+ informations.add(Element.new 'user').text = reference[:user] || 'fail'
172
+ informations.add(Element.new 'realName').text = reference[:realName] || "failirc-#{version}"
173
+
174
+ servers = @config.elements['config/servers']
175
+
176
+ if reference[:servers]
177
+ reference[:servers].each {|server|
178
+ element = servers.add(Element.new 'server')
179
+
180
+ element.attributes['host'] = server[:host]
181
+ element.attributes['port'] = server[:port]
182
+ element.attributes['ssl'] = server[:ssl] || 'disabled'
183
+ element.attributes['sslCert'] = server[:ssl_cert]
184
+ element.attributes['sslKey'] = server[:ssl_key]
185
+ }
186
+ end
187
+
188
+ modules = @config.elements['config/modules']
189
+
190
+ if reference[:modules]
191
+ reference[:modules].each {|mod|
192
+ element = modules.add(Element.new 'module')
193
+
194
+ element.attributes['name'] = mod[:name]
195
+ }
196
+ end
197
+ else
198
+ @config = Document.new reference
199
+ end
200
+
201
+ @configReference = reference
202
+
203
+ if !@config.elements['config/servers']
204
+ @config.elements['config'].add Element.new 'servers'
205
+ end
206
+
207
+ @config.elements.each('config/servers/server') {|server|
208
+ if !server.attributes['ssl']
209
+ server.attributes['ssl'] = 'disabled'
210
+ end
211
+ }
212
+
213
+ self.debug 'Loading modules.'
214
+
215
+ @config.elements.each('config/modules/module') {|element|
216
+ if !element.attributes['path']
217
+ element.attributes['path'] = 'failirc/client/modules'
218
+ end
219
+
220
+ self.loadModule element.attributes['name'], element.attributes['path']
221
+ }
222
+
223
+ self.debug 'Finished loading modules.', "\n"
224
+ end
225
+ end
226
+
227
+ end