failirc 0.0.1

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.
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