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