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,266 @@
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/server/clients'
29
+ require 'failirc/server/links'
30
+ require 'failirc/server/channels'
31
+ require 'failirc/server/dispatcher'
32
+
33
+ module IRC
34
+
35
+ class Server
36
+ attr_reader :version, :createdOn, :verbose, :dispatcher, :modules, :channels, :connections, :config, :data
37
+
38
+ def initialize (conf, verbose)
39
+ @version = IRC::VERSION
40
+ @createdOn = Time.now
41
+ @verbose = verbose ? true : false
42
+
43
+ @dispatcher = Dispatcher.new(self)
44
+
45
+ @modules = {}
46
+
47
+ @data = ThreadSafeHash.new
48
+
49
+ @channels = Channels.new(self)
50
+
51
+ self.config = conf
52
+ end
53
+
54
+ def clients
55
+ dispatcher.connection.clients
56
+ end
57
+
58
+ def links
59
+ dispatcher.connection.links
60
+ end
61
+
62
+ def comments
63
+ result = ''
64
+
65
+ modules.each_value {|mod|
66
+ begin
67
+ result << " #{mod.description}"
68
+ rescue
69
+ end
70
+ }
71
+
72
+ return result[1, result.length]
73
+ end
74
+
75
+ def host
76
+ @config.elements['config/server/host'].text
77
+ end
78
+
79
+ def ip
80
+ begin
81
+ return Resolv.getaddress(@config.elements['config/server/host'].text)
82
+ rescue
83
+ return Resolv.getaddress('localhost')
84
+ end
85
+ end
86
+
87
+ def name
88
+ @config.elements['config/server/name'].text
89
+ end
90
+
91
+ def loadModule (name, path=nil, reload=false)
92
+ if @modules[name] && !reload
93
+ return
94
+ end
95
+
96
+ begin
97
+ if path[0] == '/'
98
+ $LOAD_PATH.push path
99
+ require name
100
+ $LOAD_PATH.pop
101
+ else
102
+ require "#{path}/#{name}"
103
+ end
104
+
105
+ klass = eval("Modules::#{name}") rescue nil
106
+
107
+ if klass
108
+ @modules[name] = klass.new(self)
109
+ self.debug "Loaded `#{name}`."
110
+ else
111
+ raise Exception
112
+ end
113
+ rescue Exception => e
114
+ self.debug "Failed to load `#{name}`."
115
+ self.debug e
116
+ end
117
+ end
118
+
119
+ def start
120
+ if @started
121
+ return
122
+ end
123
+
124
+ if !@config
125
+ raise 'config is missing.'
126
+ end
127
+
128
+ @started = true
129
+
130
+ @config.elements.each('config/server/listen') {|listen|
131
+ self.listen({
132
+ :bind => listen.attributes['bind'],
133
+ :port => listen.attributes['port'],
134
+
135
+ :ssl => listen.attributes['ssl'],
136
+ :ssl_cert => listen.attributes['sslCert'],
137
+ :ssl_key => listen.attributes['sslKey']
138
+ }, listen)
139
+ }
140
+
141
+ @dispatcher.start
142
+ end
143
+
144
+ def stop
145
+ @stopping = true
146
+
147
+ begin
148
+ dispatcher.stop
149
+
150
+ @modules.each {|mod|
151
+ mod.finalize
152
+ }
153
+ rescue
154
+ end
155
+
156
+ @stopping = false
157
+ @started = false
158
+ end
159
+
160
+ def stopping?
161
+ @stopping
162
+ end
163
+
164
+ def listen (*args)
165
+ @dispatcher.connection.listen(*args)
166
+ end
167
+
168
+ # kill connection with harpoons on fire
169
+ def kill (thing, message=nil, force=false)
170
+ if !thing || (thing.modes[:killing] && (!force || thing.modes[:kill_forcing])) || !@dispatcher.connections.exists?(thing.socket)
171
+ return
172
+ end
173
+
174
+ if thing.is_a?(User)
175
+ thing = thing.client
176
+ end
177
+
178
+ thing.modes[:killing] = true
179
+
180
+ if force
181
+ thing.modes[:kill_forcing] = true
182
+
183
+ tmp = @dispatcher.output[thing].drop_while {|item|
184
+ item != :EOC
185
+ }
186
+
187
+ @dispatcher.output[thing].clear
188
+ @dispatcher.output[thing].insert(-1, *tmp)
189
+ end
190
+
191
+ @dispatcher.output.push(thing, :EOC)
192
+ @dispatcher.output.push(thing, message)
193
+ end
194
+
195
+ # reload the config and modules' configurations
196
+ def rehash
197
+ self.config = @configReference
198
+ end
199
+
200
+ def config= (reference)
201
+ @config = Document.new reference
202
+ @configReference = reference
203
+
204
+ if !@config.elements['config/server']
205
+ @config.elements['config'].add(Element.new('server'))
206
+ end
207
+
208
+ if !@config.elements['config/server/name']
209
+ @config.elements['config/server'].add(Element.new('name')).text = 'Fail IRC'
210
+ end
211
+
212
+ if !@config.elements['config/server/host']
213
+ @config.elements['config/server'].add(Element.new('host')).text = Socket.gethostname
214
+ end
215
+
216
+ if !@config.elements['config/server/pingTimeout']
217
+ @config.elements['config/server'].add(Element.new('pingTimeout')).text = '60'
218
+ end
219
+
220
+ if !@config.elements['config/server/listen']
221
+ @config.elements['config/server'].add(Element.new('listen'))
222
+ end
223
+
224
+ @config.elements.each('config/server/listen') {|element|
225
+ if !element.attributes['port']
226
+ element.attributes['port'] = '6667'
227
+ end
228
+
229
+ if !element.attributes['bind']
230
+ element.attributes['bind'] = '0.0.0.0'
231
+ end
232
+
233
+ if !element.attributes['ssl'] || (element.attributes['ssl'] != 'enabled' && element.attributes['ssl'] != 'disabled' && element.attributes['ssl'] != 'promiscuous')
234
+ element.attributes['ssl'] = 'disabled'
235
+ end
236
+
237
+ if element.attributes['password'] && element.attributes['password'].match(/:/)
238
+ raise 'Password CANNOT contain :'
239
+ end
240
+ }
241
+
242
+ if !@config.elements['config/modules']
243
+ @config.elements['config'].add(Element.new('modules'))
244
+ end
245
+
246
+ @modules.each_value {|mod|
247
+ mod.rehash
248
+ }
249
+
250
+ self.debug 'Loading modules.'
251
+
252
+ @config.elements.each('config/modules/module') {|element|
253
+ if !element.attributes['path']
254
+ element.attributes['path'] = 'failirc/server/modules'
255
+ end
256
+
257
+ self.loadModule element.attributes['name'], element.attributes['path']
258
+ }
259
+
260
+ self.debug 'Finished loading modules.', "\n"
261
+ end
262
+
263
+ alias to_s host
264
+ end
265
+
266
+ end
@@ -0,0 +1,122 @@
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/utils'
21
+ require 'failirc/modes'
22
+
23
+ require 'failirc/server/users'
24
+
25
+ module IRC
26
+
27
+ class Server
28
+
29
+ class Channel
30
+ class Topic
31
+ attr_reader :server, :channel, :text, :setBy
32
+ attr_accessor :setOn
33
+
34
+ def initialize (channel)
35
+ @server = channel.server
36
+ @channel = channel
37
+
38
+ @semaphore = Mutex.new
39
+ end
40
+
41
+ def text= (value)
42
+ @semaphore.synchronize {
43
+ @text = value
44
+ @setOn = Time.now
45
+ }
46
+ end
47
+
48
+ def setBy= (value)
49
+ @setBy = value.mask.clone
50
+ end
51
+
52
+ def to_s
53
+ text
54
+ end
55
+
56
+ def nil?
57
+ text.nil?
58
+ end
59
+ end
60
+
61
+ attr_reader :server, :name, :type, :createdOn, :users, :modes, :topic
62
+
63
+ def initialize (server, name)
64
+ @server = server
65
+ @name = name
66
+ @type = name[0, 1]
67
+
68
+ @createdOn = Time.now
69
+ @users = Users.new(self)
70
+ @modes = Modes.new
71
+ @topic = Topic.new(self)
72
+
73
+ @semaphore = Mutex.new
74
+ end
75
+
76
+ def type
77
+ @name[0, 1]
78
+ end
79
+
80
+ def topic= (data)
81
+ @semaphore.synchronize {
82
+ if data.is_a?(Topic)
83
+ @topic = data
84
+ elsif data.is_a?(Array)
85
+ @topic.setBy = data[0]
86
+ @topic.text = data[1]
87
+ end
88
+ }
89
+ end
90
+
91
+ def [] (user)
92
+ users[user]
93
+ end
94
+
95
+ def add (user)
96
+ users.add(user)
97
+ end
98
+
99
+ def delete (user)
100
+ users.delete(user)
101
+ end
102
+
103
+ def user (client)
104
+ return @users[client.nick]
105
+ end
106
+
107
+ def empty?
108
+ return @users.empty?
109
+ end
110
+
111
+ def send (*args)
112
+ users.send(*args)
113
+ end
114
+
115
+ def to_s
116
+ @name
117
+ end
118
+ end
119
+
120
+ end
121
+
122
+ end
@@ -0,0 +1,84 @@
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/extensions'
21
+ require 'failirc/server/clients'
22
+ require 'failirc/server/channel'
23
+
24
+ module IRC
25
+
26
+ class Server
27
+
28
+ class Channels < ThreadSafeHash
29
+ attr_reader :server
30
+
31
+ def initialize (server, *args)
32
+ @server = server
33
+
34
+ super(*args)
35
+ end
36
+
37
+ alias __delete delete
38
+
39
+ def delete (channel)
40
+ if channel.is_a?(Channel)
41
+ __delete(channel.name)
42
+ else
43
+ __delete(channel)
44
+ end
45
+ end
46
+
47
+ def add (channel)
48
+ self[channel.name] = channel
49
+ end
50
+
51
+ # get single users in the channels
52
+ def unique_users
53
+ result = Clients.new(server)
54
+
55
+ each_value {|channel|
56
+ channel.users.each {|nick, user|
57
+ result[nick] = user.client
58
+ }
59
+ }
60
+
61
+ return result
62
+ end
63
+
64
+ def to_s (thing=nil)
65
+ result = ''
66
+
67
+
68
+ if thing.is_a?(Client) || thing.is_a?(User)
69
+ each_value {|channel|
70
+ result << " #{channel.user(thing).modes[:level]}#{channel.name}"
71
+ }
72
+ else
73
+ each_value {|channel|
74
+ result << " #{channel.name}"
75
+ }
76
+ end
77
+
78
+ return result[1, result.length]
79
+ end
80
+ end
81
+
82
+ end
83
+
84
+ end