Branch data Line data Source code
1 : : // $Id: IRC.cc 4582 2007-07-04 01:14:09Z vern $
2 : :
3 : : // An IRC analyzer contributed by Roland Gruber.
4 : :
5 : : #include <iostream>
6 : : #include "IRC.h"
7 : : #include "DPM.h"
8 : : #include "ContentLine.h"
9 : : #include "NetVar.h"
10 : : #include "Event.h"
11 : : #include "ZIP.h"
12 : :
13 : :
14 : 0 : IRC_Analyzer::IRC_Analyzer(Connection* conn)
15 : 0 : : TCP_ApplicationAnalyzer(AnalyzerTag::IRC, conn)
16 : : {
17 : 0 : invalid_msg_count = 0;
18 : 0 : invalid_msg_max_count = 20;
19 : 0 : orig_status = WAIT_FOR_REGISTRATION;
20 : 0 : resp_status = WAIT_FOR_REGISTRATION;
21 : 0 : orig_zip_status = NO_ZIP;
22 : 0 : resp_zip_status = NO_ZIP;
23 : 0 : AddSupportAnalyzer(new ContentLine_Analyzer(conn, true));
24 : 0 : AddSupportAnalyzer(new ContentLine_Analyzer(conn, false));
25 : 0 : }
26 : :
27 : 1 : bool IRC_Analyzer::Available()
28 : : {
29 : : static bool did_avail = false;
30 : : static bool avail = false;
31 : :
32 [ + - ]: 1 : if ( ! did_avail )
33 : : {
34 : : // It's a lot of events, but for consistency with other
35 : : // analyzers we need to check for all of them.
36 : : avail = irc_client || irc_server || irc_request || irc_reply ||
37 : : irc_message || irc_enter_message || irc_quit_message ||
38 : : irc_privmsg_message || irc_notice_message ||
39 : : irc_squery_message || irc_join_message ||
40 : : irc_part_message || irc_nick_message ||
41 : : irc_invalid_nick || irc_network_info ||
42 : : irc_server_info || irc_channel_info || irc_who_line ||
43 : : irc_who_message || irc_whois_message ||
44 : : irc_whois_user_line || irc_whois_operator_line ||
45 : : irc_whois_channel_line || irc_oper_message ||
46 : : irc_oper_response || irc_kick_message ||
47 : : irc_error_message || irc_invite_message ||
48 : : irc_mode_message || irc_squit_message ||
49 : : irc_names_info || irc_dcc_message ||
50 : : irc_global_users || irc_user_message ||
51 [ + - ][ + - ]: 1 : irc_channel_topic || irc_password_message;
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ - + ]
52 : :
53 : 1 : did_avail = true;
54 : : }
55 : :
56 : 1 : return avail;
57 : : }
58 : :
59 : 0 : void IRC_Analyzer::Done()
60 : : {
61 : 0 : TCP_ApplicationAnalyzer::Done();
62 : 0 : }
63 : :
64 : 0 : void IRC_Analyzer::DeliverStream(int length, const u_char* line, bool orig)
65 : : {
66 : 0 : TCP_ApplicationAnalyzer::DeliverStream(length, line, orig);
67 : :
68 : : // check line size
69 [ # # ]: 0 : if ( length > 512 )
70 : : {
71 : 0 : Weird("irc_line_size_exceeded");
72 : 0 : return;
73 : : }
74 : :
75 [ # # ]: 0 : if ( length < 2 )
76 : : {
77 : 0 : Weird("irc_line_too_short");
78 : 0 : return;
79 : : }
80 : :
81 : 0 : string myline = string((const char*) line);
82 : :
83 : : // Check for prefix.
84 : 0 : string prefix = "";
85 [ # # ]: 0 : if ( line[0] == ':' )
86 : : { // find end of prefix and extract it
87 : 0 : unsigned int pos = myline.find(' ');
88 [ # # ]: 0 : if ( pos > (unsigned int) length )
89 : : {
90 : 0 : Weird("irc_invalid_line");
91 : 0 : return;
92 : : }
93 : :
94 : 0 : prefix = myline.substr(1, pos - 1);
95 : 0 : myline = myline.substr(pos + 1); // remove prefix from line
96 : : }
97 : :
98 : :
99 [ # # ]: 0 : if ( orig )
100 : : {
101 : 0 : ProtocolConfirmation();
102 [ # # ]: 0 : if ( irc_client )
103 : : {
104 : 0 : val_list* vl = new val_list;
105 : 0 : vl->append(BuildConnVal());
106 : 0 : vl->append(new StringVal(prefix.c_str()));
107 : 0 : vl->append(new StringVal(myline.c_str()));
108 : 0 : ConnectionEvent(irc_client, vl);
109 : : }
110 : : }
111 : : else
112 : : {
113 [ # # ]: 0 : if ( irc_server )
114 : : {
115 : 0 : val_list* vl = new val_list;
116 : 0 : vl->append(BuildConnVal());
117 : 0 : vl->append(new StringVal(prefix.c_str()));
118 : 0 : vl->append(new StringVal(myline.c_str()));
119 : 0 : ConnectionEvent(irc_server, vl);
120 : : }
121 : : }
122 : :
123 : 0 : int code = 0;
124 : 0 : string command = "";
125 : :
126 : : // Check if line is long enough to include status code or command.
127 [ # # ]: 0 : if ( myline.size() < 4 )
128 : : {
129 : 0 : Weird("irc_invalid_line");
130 : 0 : ProtocolViolation("line too short");
131 : : return;
132 : : }
133 : :
134 : : // Check if this is a server reply.
135 [ # # ]: 0 : if ( isdigit(myline[0]) )
136 : : {
137 [ # # ][ # # ]: 0 : if ( isdigit(myline[1]) && isdigit(myline[2]) &&
[ # # ][ # # ]
138 : : myline[3] == ' ')
139 : : {
140 : : code = (myline[0] - '0') * 100 +
141 : 0 : (myline[1] - '0') * 10 + (myline[2] - '0');
142 : 0 : myline = myline.substr(4);
143 : : }
144 : : else
145 : : {
146 : 0 : Weird("irc_invalid_reply_number");
147 : 0 : ProtocolViolation("invalid reply number");
148 : : return;
149 : : }
150 : : }
151 : : else
152 : : { // get command
153 : 0 : unsigned int pos = myline.find(' ');
154 [ # # ]: 0 : if ( pos > (unsigned int) length )
155 : : {
156 : 0 : Weird("irc_invalid_line");
157 : : return;
158 : : }
159 : :
160 : 0 : command = myline.substr(0, pos);
161 [ # # ]: 0 : for ( unsigned int i = 0; i < command.size(); ++i )
162 : 0 : command[i] = toupper(command[i]);
163 : :
164 : 0 : myline = myline.substr(pos + 1);
165 : : }
166 : :
167 : : // Extract parameters.
168 : 0 : string params = myline;
169 : :
170 : : // Check for Server2Server - connections with ZIP enabled.
171 [ # # # # ]: 0 : if ( orig && orig_status == WAIT_FOR_REGISTRATION )
172 : : {
173 [ # # ]: 0 : if ( command == "PASS" )
174 : : {
175 : 0 : vector<string> p = SplitWords(params,' ');
176 [ # # # # ]: 0 : if ( p.size() > 3 &&
[ # # ][ # # ]
177 : : (p[3].find('Z')<=p[3].size() ||
178 : : p[3].find('z')<=p[3].size()) )
179 : 0 : orig_zip_status = ACCEPT_ZIP;
180 : : else
181 : 0 : orig_zip_status = NO_ZIP;
182 : : }
183 : :
184 : : // We do not check if SERVER command is successful, since
185 : : // the connection will be terminated by the server if
186 : : // authentication fails.
187 : : //
188 : : // (### This seems not quite prudent to me - VP)
189 [ # # ][ # # ]: 0 : if ( command == "SERVER" && prefix == "")
[ # # ]
190 : : {
191 : 0 : orig_status = REGISTERED;
192 : : }
193 : : }
194 : :
195 [ # # ][ # # ]: 0 : if ( ! orig && resp_status == WAIT_FOR_REGISTRATION )
196 : : {
197 [ # # ]: 0 : if ( command == "PASS" )
198 : : {
199 : 0 : vector<string> p = SplitWords(params,' ');
200 [ # # # # ]: 0 : if ( p.size() > 3 &&
[ # # ][ # # ]
201 : : (p[3].find('Z')<=p[3].size() ||
202 : : p[3].find('z')<=p[3].size()) )
203 : 0 : resp_zip_status = ACCEPT_ZIP;
204 : : else
205 : 0 : resp_zip_status = NO_ZIP;
206 : :
207 : : }
208 : :
209 : : // Again, don't bother checking whether SERVER command
210 : : // is successful.
211 [ # # ][ # # ]: 0 : if ( command == "SERVER" && prefix == "")
[ # # ]
212 : 0 : resp_status = REGISTERED;
213 : : }
214 : :
215 : : // Analyze server reply messages.
216 [ # # ]: 0 : if ( code > 0 )
217 : : {
218 [ # # # # # : 0 : switch ( code ) {
# # # # #
# # # # ]
219 : : // Ignore unimportant messages.
220 : : case 1: // RPL_WELCOME
221 : : case 2: // RPL_YOURHOST
222 : : case 3: // RPL_CREATED
223 : : case 4: // RPL_MYINFO
224 : : case 5: // RPL_BOUNCE
225 : : case 252: // number of ops online
226 : : case 253: // number of unknown connections
227 : : case 265: // RPL_LOCALUSERS
228 : : case 312: // whois server reply
229 : : case 315: // end of who list
230 : : case 317: // whois idle reply
231 : : case 318: // end of whois list
232 : : case 366: // end of names list
233 : : case 372: // RPL_MOTD
234 : : case 375: // RPL_MOTDSTART
235 : : case 376: // RPL_ENDOFMOTD
236 : : case 331: // RPL_NOTOPIC
237 : 0 : break;
238 : :
239 : : // Count of users, services and servers in whole network.
240 : : case 251:
241 [ # # ]: 0 : if ( ! irc_network_info )
242 : 0 : break;
243 : :
244 : : {
245 : 0 : vector<string> parts = SplitWords(params, ' ');
246 : 0 : int users = 0;
247 : 0 : int services = 0;
248 : 0 : int servers = 0;
249 : :
250 [ # # ]: 0 : for ( unsigned int i = 1; i < parts.size(); ++i )
251 : : {
252 [ # # ]: 0 : if ( parts[i] == "users" )
253 : 0 : users = atoi(parts[i-1].c_str());
254 [ # # ]: 0 : else if ( parts[i] == "services" )
255 : 0 : services = atoi(parts[i-1].c_str());
256 [ # # ]: 0 : else if ( parts[i] == "servers" )
257 : 0 : servers = atoi(parts[i-1].c_str());
258 : : // else ###
259 : : }
260 : :
261 : 0 : val_list* vl = new val_list;
262 : 0 : vl->append(BuildConnVal());
263 : 0 : vl->append(new Val(users, TYPE_INT));
264 : 0 : vl->append(new Val(services, TYPE_INT));
265 : 0 : vl->append(new Val(servers, TYPE_INT));
266 : :
267 : 0 : ConnectionEvent(irc_network_info, vl);
268 : : }
269 : 0 : break;
270 : :
271 : : // List of users in a channel (names command).
272 : : case 353:
273 [ # # ]: 0 : if ( ! irc_names_info )
274 : 0 : break;
275 : :
276 : : {
277 : 0 : vector<string> parts = SplitWords(params, ' ');
278 : :
279 : : // Remove nick name.
280 : 0 : parts.erase(parts.begin());
281 [ # # ]: 0 : if ( parts.size() < 2 )
282 : : {
283 : 0 : Weird("irc_invalid_names_line");
284 : : return;
285 : : }
286 : :
287 : 0 : string type = parts[0];
288 : 0 : string channel = parts[1];
289 : :
290 : : // Remove type and channel.
291 : 0 : parts.erase(parts.begin());
292 : 0 : parts.erase(parts.begin());
293 : :
294 [ # # # # ]: 0 : if ( parts.size() > 0 && parts[0][0] == ':' )
[ # # ]
295 : 0 : parts[0] = parts[0].substr(1);
296 : :
297 : 0 : val_list* vl = new val_list;
298 : 0 : vl->append(BuildConnVal());
299 : 0 : vl->append(new StringVal(type.c_str()));
300 : 0 : vl->append(new StringVal(channel.c_str()));
301 : :
302 : 0 : TableVal* set = new TableVal(string_set);
303 [ # # ]: 0 : for ( unsigned int i = 0; i < parts.size(); ++i )
304 : : {
305 [ # # ]: 0 : if ( parts[i][0] == '@' )
306 : 0 : parts[i] = parts[i].substr(1);
307 : 0 : set->Assign(new StringVal(parts[i].c_str()), 0);
308 : : }
309 : 0 : vl->append(set);
310 : :
311 [ # # ]: 0 : ConnectionEvent(irc_names_info, vl);
312 : : }
313 : 0 : break;
314 : :
315 : : // Count of users and services on this server.
316 : : case 255:
317 [ # # ]: 0 : if ( ! irc_server_info )
318 : 0 : break;
319 : :
320 : : {
321 : 0 : vector<string> parts = SplitWords(params, ' ');
322 : 0 : int users = 0;
323 : 0 : int services = 0;
324 : 0 : int servers = 0;
325 : :
326 [ # # ]: 0 : for ( unsigned int i = 1; i < parts.size(); ++i )
327 : : {
328 [ # # ]: 0 : if ( parts[i] == "users," )
329 : 0 : users = atoi(parts[i-1].c_str());
330 [ # # ]: 0 : else if ( parts[i] == "clients" )
331 : 0 : users = atoi(parts[i-1].c_str());
332 [ # # ]: 0 : else if ( parts[i] == "services" )
333 : 0 : services = atoi(parts[i-1].c_str());
334 [ # # ]: 0 : else if ( parts[i] == "servers" )
335 : 0 : servers = atoi(parts[i-1].c_str());
336 : : // else ###
337 : : }
338 : :
339 : 0 : val_list* vl = new val_list;
340 : 0 : vl->append(BuildConnVal());
341 : 0 : vl->append(new Val(users, TYPE_INT));
342 : 0 : vl->append(new Val(services, TYPE_INT));
343 : 0 : vl->append(new Val(servers, TYPE_INT));
344 : :
345 : 0 : ConnectionEvent(irc_server_info, vl);
346 : : }
347 : 0 : break;
348 : :
349 : : // Count of channels.
350 : : case 254:
351 [ # # ]: 0 : if ( ! irc_channel_info )
352 : 0 : break;
353 : :
354 : : {
355 : 0 : vector<string> parts = SplitWords(params, ' ');
356 : 0 : int channels = 0;
357 [ # # ]: 0 : for ( unsigned int i = 1; i < parts.size(); ++i )
358 [ # # ]: 0 : if ( parts[i] == ":channels" )
359 : 0 : channels = atoi(parts[i - 1].c_str());
360 : :
361 : 0 : val_list* vl = new val_list;
362 : 0 : vl->append(BuildConnVal());
363 : 0 : vl->append(new Val(channels, TYPE_INT));
364 : :
365 : 0 : ConnectionEvent(irc_channel_info, vl);
366 : : }
367 : 0 : break;
368 : :
369 : : // RPL_GLOBALUSERS
370 : : case 266:
371 : : {
372 : : // FIXME: We should really streamline all this
373 : : // parsing code ...
374 [ # # ]: 0 : if ( ! irc_global_users )
375 : 0 : break;
376 : :
377 : 0 : const char* prefix = params.c_str();
378 : :
379 : 0 : const char* eop = strchr(prefix, ' ');
380 [ # # ]: 0 : if ( ! eop )
381 : : {
382 : 0 : Weird("invalid_irc_global_users_reply");
383 : 0 : break;
384 : : }
385 : :
386 : 0 : const char *msg = strchr(++eop, ':');
387 [ # # ]: 0 : if ( ! msg )
388 : : {
389 : 0 : Weird("invalid_irc_global_users_reply");
390 : 0 : break;
391 : : }
392 : :
393 : 0 : val_list* vl = new val_list;
394 : 0 : vl->append(BuildConnVal());
395 : 0 : vl->append(new StringVal(eop - prefix, prefix));
396 : 0 : vl->append(new StringVal(++msg));
397 : 0 : ConnectionEvent(irc_global_users, vl);
398 : 0 : break;
399 : : }
400 : :
401 : : // WHOIS user reply line.
402 : : case 311:
403 [ # # ]: 0 : if ( ! irc_whois_user_line )
404 : 0 : break;
405 : :
406 : : {
407 : 0 : vector<string> parts = SplitWords(params, ' ');
408 : :
409 [ # # ]: 0 : if ( parts.size() > 1 )
410 : 0 : parts.erase(parts.begin());
411 [ # # ]: 0 : if ( parts.size() < 5 )
412 : : {
413 : 0 : Weird("irc_invalid_whois_user_line");
414 : : return;
415 : : }
416 : :
417 : 0 : val_list* vl = new val_list;
418 : 0 : vl->append(BuildConnVal());
419 : 0 : vl->append(new StringVal(parts[0].c_str()));
420 : 0 : vl->append(new StringVal(parts[1].c_str()));
421 : 0 : vl->append(new StringVal(parts[2].c_str()));
422 : :
423 : 0 : parts.erase(parts.begin(), parts.begin() + 4);
424 : :
425 : 0 : string real_name = parts[0];
426 [ # # ]: 0 : for ( unsigned int i = 1; i < parts.size(); ++i )
427 : 0 : real_name = real_name + " " + parts[i];
428 : :
429 [ # # ]: 0 : if ( real_name[0] == ':' )
430 : 0 : real_name = real_name.substr(1);
431 : :
432 : 0 : vl->append(new StringVal(real_name.c_str()));
433 : :
434 [ # # ]: 0 : ConnectionEvent(irc_whois_user_line, vl);
435 : : }
436 : 0 : break;
437 : :
438 : : // WHOIS operator reply line.
439 : : case 313:
440 [ # # ]: 0 : if ( ! irc_whois_operator_line )
441 : 0 : break;
442 : :
443 : : {
444 : 0 : vector<string> parts = SplitWords(params, ' ');
445 : :
446 [ # # ]: 0 : if ( parts.size() > 1 )
447 : 0 : parts.erase(parts.begin());
448 : :
449 [ # # ]: 0 : if ( parts.size() < 2 )
450 : : {
451 : 0 : Weird("irc_invalid_whois_operator_line");
452 : : return;
453 : : }
454 : :
455 : 0 : val_list* vl = new val_list;
456 : 0 : vl->append(BuildConnVal());
457 : 0 : vl->append(new StringVal(parts[0].c_str()));
458 : :
459 [ # # ]: 0 : ConnectionEvent(irc_whois_operator_line, vl);
460 : : }
461 : 0 : break;
462 : :
463 : : // WHOIS channel reply.
464 : : case 319:
465 [ # # ]: 0 : if ( ! irc_whois_channel_line )
466 : 0 : break;
467 : :
468 : : {
469 : 0 : vector<string> parts = SplitWords(params, ' ');
470 : :
471 : : // Remove nick name.
472 : 0 : parts.erase(parts.begin());
473 [ # # ]: 0 : if ( parts.size() < 2 )
474 : : {
475 : 0 : Weird("irc_invalid_whois_channel_line");
476 : : return;
477 : : }
478 : :
479 : 0 : string nick = parts[0];
480 : 0 : parts.erase(parts.begin());
481 : :
482 [ # # # # ]: 0 : if ( parts.size() > 0 && parts[0][0] == ':' )
[ # # ]
483 : 0 : parts[0] = parts[0].substr(1);
484 : :
485 : 0 : val_list* vl = new val_list;
486 : 0 : vl->append(BuildConnVal());
487 : 0 : vl->append(new StringVal(nick.c_str()));
488 : 0 : TableVal* set = new TableVal(string_set);
489 [ # # ]: 0 : for ( unsigned int i = 0; i < parts.size(); ++i )
490 : : {
491 : 0 : Val* idx = new StringVal(parts[i].c_str());
492 : 0 : set->Assign(idx, 0);
493 : 0 : Unref(idx);
494 : : }
495 : :
496 : 0 : vl->append(set);
497 : :
498 [ # # ]: 0 : ConnectionEvent(irc_whois_channel_line, vl);
499 : : }
500 : 0 : break;
501 : :
502 : : // RPL_TOPIC reply.
503 : : case 332:
504 : : {
505 [ # # ]: 0 : if ( ! irc_channel_topic )
506 : 0 : break;
507 : :
508 : 0 : vector<string> parts = SplitWords(params, ' ');
509 [ # # ]: 0 : if ( parts.size() < 4 )
510 : : {
511 : 0 : Weird("irc_invalid_topic_reply");
512 : : return;
513 : : }
514 : :
515 : 0 : unsigned int pos = params.find(':');
516 [ # # ]: 0 : if ( pos < params.size() )
517 : : {
518 : 0 : string topic = params.substr(pos + 1);
519 : 0 : val_list* vl = new val_list;
520 : :
521 : 0 : vl->append(BuildConnVal());
522 : 0 : vl->append(new StringVal(parts[1].c_str()));
523 : :
524 : 0 : const char* t = topic.c_str();
525 [ # # ]: 0 : if ( *t == ':' )
526 : 0 : ++t;
527 : :
528 : 0 : vl->append(new StringVal(t));
529 : :
530 : 0 : ConnectionEvent(irc_channel_topic, vl);
531 : : }
532 : : else
533 : : {
534 : 0 : Weird("irc_invalid_topic_reply");
535 : : return;
536 : : }
537 [ # # ]: 0 : break;
538 : : }
539 : :
540 : : // WHO reply line.
541 : : case 352:
542 [ # # ]: 0 : if ( ! irc_who_line )
543 : 0 : break;
544 : :
545 : : {
546 : 0 : vector<string> parts = SplitWords(params, ' ');
547 [ # # ]: 0 : if ( parts.size() < 9 )
548 : : {
549 : 0 : Weird("irc_invalid_who_line");
550 : : return;
551 : : }
552 : :
553 : 0 : val_list* vl = new val_list;
554 : 0 : vl->append(BuildConnVal());
555 : 0 : vl->append(new StringVal(parts[0].c_str()));
556 : 0 : vl->append(new StringVal(parts[1].c_str()));
557 [ # # ]: 0 : if ( parts[2][0] == '~' )
558 : 0 : parts[2] = parts[2].substr(1);
559 : 0 : vl->append(new StringVal(parts[2].c_str()));
560 : 0 : vl->append(new StringVal(parts[3].c_str()));
561 : 0 : vl->append(new StringVal(parts[4].c_str()));
562 : 0 : vl->append(new StringVal(parts[5].c_str()));
563 : 0 : vl->append(new StringVal(parts[6].c_str()));
564 [ # # ]: 0 : if ( parts[7][0] == ':' )
565 : 0 : parts[7] = parts[7].substr(1);
566 : 0 : vl->append(new Val(atoi(parts[7].c_str()), TYPE_INT));
567 : 0 : vl->append(new StringVal(parts[8].c_str()));
568 : :
569 [ # # ]: 0 : ConnectionEvent(irc_who_line, vl);
570 : : }
571 : 0 : break;
572 : :
573 : : // Invalid nick name.
574 : : case 431:
575 : : case 432:
576 : : case 433:
577 : : case 436:
578 [ # # ]: 0 : if ( irc_invalid_nick )
579 : : {
580 : 0 : val_list* vl = new val_list;
581 : 0 : vl->append(BuildConnVal());
582 : 0 : ConnectionEvent(irc_invalid_nick, vl);
583 : : }
584 : 0 : break;
585 : :
586 : : // Operator responses.
587 : : case 381: // User is operator
588 : : case 491: // user is not operator
589 [ # # ]: 0 : if ( irc_oper_response )
590 : : {
591 : 0 : val_list* vl = new val_list;
592 : 0 : vl->append(BuildConnVal());
593 : 0 : vl->append(new Val(code == 381, TYPE_BOOL));
594 : 0 : ConnectionEvent(irc_oper_response, vl);
595 : : }
596 : 0 : break;
597 : :
598 : : // All other server replies.
599 : : default:
600 : 0 : val_list* vl = new val_list;
601 : 0 : vl->append(BuildConnVal());
602 : 0 : vl->append(new StringVal(prefix.c_str()));
603 : 0 : vl->append(new Val(code, TYPE_COUNT));
604 : 0 : vl->append(new StringVal(params.c_str()));
605 : :
606 : 0 : ConnectionEvent(irc_reply, vl);
607 : : break;
608 : : }
609 : : return;
610 : : }
611 : :
612 : : // Check if command is valid.
613 [ # # ]: 0 : if ( command.size() > 20 )
614 : : {
615 : 0 : Weird("irc_invalid_command");
616 [ # # ]: 0 : if ( ++invalid_msg_count > invalid_msg_max_count )
617 : : {
618 : 0 : Weird("irc_too_many_invalid");
619 : 0 : ProtocolViolation("too many long lines");
620 : : return;
621 : : }
622 : : return;
623 : : }
624 : :
625 [ # # ][ # # ]: 0 : else if ( irc_privmsg_message && command == "PRIVMSG")
[ # # ]
626 : : {
627 : 0 : unsigned int pos = params.find(' ');
628 [ # # ]: 0 : if ( pos >= params.size() )
629 : : {
630 : 0 : Weird("irc_invalid_privmsg_message_format");
631 : : return;
632 : : }
633 : :
634 : 0 : string target = params.substr(0, pos);
635 : 0 : string message = params.substr(pos + 1);
636 : :
637 [ # # # # ]: 0 : if ( message.size() > 0 && message[0] == ':' )
[ # # ]
638 : 0 : message = message.substr(1);
639 [ # # ][ # # ]: 0 : if ( message.size() > 0 && message[0] == 1 )
[ # # ]
640 : 0 : message = message.substr(1); // DCC
641 : :
642 : : // Check for DCC messages.
643 [ # # ][ # # ]: 0 : if ( message.size() > 3 && message.substr(0, 3) == "DCC" )
[ # # ][ # # ]
[ # # ]
644 : : {
645 [ # # ][ # # ]: 0 : if ( message.size() > 0 &&
[ # # ]
646 : : message[message.size() - 1] == 1 )
647 : 0 : message = message.substr(0, message.size() - 1);
648 : :
649 : 0 : vector<string> parts = SplitWords(message, ' ');
650 [ # # # # ]: 0 : if ( parts.size() < 5 || parts.size() > 6 )
[ # # ]
651 : : {
652 : 0 : Weird("irc_invalid_dcc_message_format");
653 : : return;
654 : : }
655 : :
656 : : // Calculate IP address.
657 : 0 : uint32 raw_ip = 0;
658 [ # # ]: 0 : for ( unsigned int i = 0; i < parts[3].size(); ++i )
659 : : {
660 : 0 : string s = parts[3].substr(i, 1);
661 : 0 : raw_ip = (10 * raw_ip) + atoi(s.c_str());
662 : : }
663 : :
664 : 0 : val_list* vl = new val_list;
665 : 0 : vl->append(BuildConnVal());
666 : 0 : vl->append(new StringVal(prefix.c_str()));
667 : 0 : vl->append(new StringVal(target.c_str()));
668 : 0 : vl->append(new StringVal(parts[1].c_str()));
669 : 0 : vl->append(new StringVal(parts[2].c_str()));
670 : 0 : vl->append(new AddrVal(htonl(raw_ip)));
671 : 0 : vl->append(new Val(atoi(parts[4].c_str()), TYPE_INT));
672 [ # # ]: 0 : if ( parts.size() == 6 )
673 : : vl->append(new Val(atoi(parts[5].c_str()),
674 : 0 : TYPE_INT));
675 : : else
676 : 0 : vl->append(new Val(0, TYPE_INT));
677 : :
678 [ # # ]: 0 : ConnectionEvent(irc_dcc_message, vl);
679 : : }
680 : :
681 : : else
682 : : {
683 : 0 : val_list* vl = new val_list;
684 : 0 : vl->append(BuildConnVal());
685 : 0 : vl->append(new StringVal(prefix.c_str()));
686 : 0 : vl->append(new StringVal(target.c_str()));
687 : 0 : vl->append(new StringVal(message.c_str()));
688 : :
689 : 0 : ConnectionEvent(irc_privmsg_message, vl);
690 [ # # ][ # # ]: 0 : }
691 : : }
692 : :
693 [ # # ][ # # ]: 0 : else if ( irc_notice_message && command == "NOTICE" )
[ # # ]
694 : : {
695 : 0 : unsigned int pos = params.find(' ');
696 [ # # ]: 0 : if ( pos >= params.size() )
697 : : {
698 : 0 : Weird("irc_invalid_notice_message_format");
699 : : return;
700 : : }
701 : :
702 : 0 : string target = params.substr(0, pos);
703 : 0 : string message = params.substr(pos + 1);
704 [ # # ]: 0 : if ( message[0] == ':' )
705 : 0 : message = message.substr(1);
706 : :
707 : 0 : val_list* vl = new val_list;
708 : 0 : vl->append(BuildConnVal());
709 : 0 : vl->append(new StringVal(prefix.c_str()));
710 : 0 : vl->append(new StringVal(target.c_str()));
711 : 0 : vl->append(new StringVal(message.c_str()));
712 : :
713 : 0 : ConnectionEvent(irc_notice_message, vl);
714 : : }
715 : :
716 [ # # ][ # # ]: 0 : else if ( irc_squery_message && command == "SQUERY" )
[ # # ]
717 : : {
718 : 0 : unsigned int pos = params.find(' ');
719 [ # # ]: 0 : if ( pos >= params.size() )
720 : : {
721 : 0 : Weird("irc_invalid_squery_message_format");
722 : : return;
723 : : }
724 : :
725 : 0 : string target = params.substr(0, pos);
726 : 0 : string message = params.substr(pos + 1);
727 [ # # ]: 0 : if ( message[0] == ':' )
728 : 0 : message = message.substr(1);
729 : :
730 : 0 : val_list* vl = new val_list;
731 : 0 : vl->append(BuildConnVal());
732 : 0 : vl->append(new StringVal(prefix.c_str()));
733 : 0 : vl->append(new StringVal(target.c_str()));
734 : 0 : vl->append(new StringVal(message.c_str()));
735 : :
736 : 0 : ConnectionEvent(irc_squery_message, vl);
737 : : }
738 : :
739 [ # # ][ # # ]: 0 : else if ( irc_user_message && command == "USER" )
[ # # ]
740 : : {
741 : : // extract username and real name
742 : 0 : vector<string> parts = SplitWords(params, ' ');
743 : 0 : val_list* vl = new val_list;
744 : 0 : vl->append(BuildConnVal());
745 : :
746 [ # # ]: 0 : if ( parts.size() > 0 )
747 : 0 : vl->append(new StringVal(parts[0].c_str()));
748 : 0 : else vl->append(new StringVal(""));
749 : :
750 [ # # ]: 0 : if ( parts.size() > 1 )
751 : 0 : vl->append(new StringVal(parts[1].c_str()));
752 : 0 : else vl->append(new StringVal(""));
753 : :
754 [ # # ]: 0 : if ( parts.size() > 2 )
755 : 0 : vl->append(new StringVal(parts[2].c_str()));
756 : 0 : else vl->append(new StringVal(""));
757 : :
758 : 0 : string realname;
759 [ # # ]: 0 : for ( unsigned int i = 3; i < parts.size(); i++ )
760 : : {
761 : 0 : realname += parts[i];
762 [ # # ]: 0 : if ( i > 3 )
763 : 0 : realname += " ";
764 : : }
765 : :
766 : 0 : const char* name = realname.c_str();
767 [ # # ]: 0 : vl->append(new StringVal(*name == ':' ? name + 1 : name));
768 : :
769 : 0 : ConnectionEvent(irc_user_message, vl);
770 : : }
771 : :
772 [ # # ][ # # ]: 0 : else if ( irc_oper_message && command == "OPER" )
[ # # ]
773 : : {
774 : : // extract username and password
775 : 0 : vector<string> parts = SplitWords(params, ' ');
776 [ # # ]: 0 : if ( parts.size() == 2 )
777 : : {
778 : 0 : val_list* vl = new val_list;
779 : 0 : vl->append(BuildConnVal());
780 : 0 : vl->append(new StringVal(parts[0].c_str()));
781 : 0 : vl->append(new StringVal(parts[1].c_str()));
782 : :
783 : 0 : ConnectionEvent(irc_oper_message, vl);
784 : : }
785 : :
786 : : else
787 : 0 : Weird("irc_invalid_oper_message_format");
788 : : }
789 : :
790 [ # # ][ # # ]: 0 : else if ( irc_kick_message && command == "KICK" )
[ # # ]
791 : : {
792 : : // Extract channels, users and comment.
793 : 0 : vector<string> parts = SplitWords(params, ' ');
794 [ # # ]: 0 : if ( parts.size() <= 1 )
795 : : {
796 : 0 : Weird("irc_invalid_kick_message_format");
797 : : return;
798 : : }
799 : :
800 : 0 : val_list* vl = new val_list;
801 : 0 : vl->append(BuildConnVal());
802 : 0 : vl->append(new StringVal(prefix.c_str()));
803 : 0 : vl->append(new StringVal(parts[0].c_str()));
804 : 0 : vl->append(new StringVal(parts[1].c_str()));
805 [ # # ]: 0 : if ( parts.size() > 2 )
806 : : {
807 : 0 : string comment = parts[2];
808 [ # # ]: 0 : for ( unsigned int i = 3; i < parts.size(); ++i )
809 : 0 : comment += " " + parts[i];
810 : :
811 [ # # ]: 0 : if ( comment[0] == ':' )
812 : 0 : comment = comment.substr(1);
813 : :
814 : 0 : vl->append(new StringVal(comment.c_str()));
815 : : }
816 : : else
817 : 0 : vl->append(new StringVal(""));
818 : :
819 [ # # ]: 0 : ConnectionEvent(irc_kick_message, vl);
820 : : }
821 : :
822 [ # # ][ # # ]: 0 : else if ( irc_join_message && command == "JOIN" )
[ # # ]
823 : : {
824 [ # # ]: 0 : if ( params[0] == ':' )
825 : 0 : params = params.substr(1);
826 : :
827 : 0 : vector<string> parts = SplitWords(params, ' ');
828 : :
829 [ # # ]: 0 : if ( parts.size() < 1 )
830 : : {
831 : 0 : Weird("irc_invalid_join_line");
832 : : return;
833 : : }
834 : :
835 : 0 : string nickname = "";
836 [ # # ]: 0 : if ( prefix.size() > 0 )
837 : : {
838 : 0 : unsigned int pos = prefix.find('!');
839 [ # # ]: 0 : if ( pos < prefix.size() )
840 : 0 : nickname = prefix.substr(0, pos);
841 : : }
842 : :
843 : 0 : val_list* vl = new val_list;
844 : 0 : vl->append(BuildConnVal());
845 : :
846 : 0 : TableVal* list = new TableVal(irc_join_list);
847 : 0 : vector<string> channels = SplitWords(parts[0], ',');
848 : 0 : vector<string> passwords;
849 : :
850 [ # # ]: 0 : if ( parts.size() > 1 )
851 : 0 : passwords = SplitWords(parts[1], ',');
852 : :
853 : 0 : string empty_string = "";
854 [ # # ]: 0 : for ( unsigned int i = 0; i < channels.size(); ++i )
855 : : {
856 : 0 : RecordVal* info = new RecordVal(irc_join_info);
857 : 0 : info->Assign(0, new StringVal(nickname.c_str()));
858 : 0 : info->Assign(1, new StringVal(channels[i].c_str()));
859 [ # # ]: 0 : if ( i < passwords.size() )
860 : 0 : info->Assign(2, new StringVal(passwords[i].c_str()));
861 : : else
862 : 0 : info->Assign(2, new StringVal(empty_string.c_str()));
863 : : // User mode.
864 : 0 : info->Assign(3, new StringVal(empty_string.c_str()));
865 : 0 : list->Assign(info, 0);
866 : 0 : Unref(info);
867 : : }
868 : :
869 : 0 : vl->append(list);
870 : :
871 [ # # ]: 0 : ConnectionEvent(irc_join_message, vl);
872 : : }
873 : :
874 [ # # ][ # # ]: 0 : else if ( irc_join_message && command == "NJOIN" )
[ # # ]
875 : : {
876 : 0 : vector<string> parts = SplitWords(params, ' ');
877 [ # # ]: 0 : if ( parts.size() != 2 )
878 : : {
879 : 0 : Weird("irc_invalid_njoin_line");
880 : : return;
881 : : }
882 : :
883 : 0 : string channel = parts[0];
884 [ # # ]: 0 : if ( parts[1][0] == ':' )
885 : 0 : parts[1] = parts[1].substr(1);
886 : :
887 : 0 : vector<string> users = SplitWords(parts[1], ',');
888 : :
889 : 0 : val_list* vl = new val_list;
890 : 0 : vl->append(BuildConnVal());
891 : :
892 : 0 : TableVal* list = new TableVal(irc_join_list);
893 : 0 : string empty_string = "";
894 : :
895 [ # # ]: 0 : for ( unsigned int i = 0; i < users.size(); ++i )
896 : : {
897 : 0 : RecordVal* info = new RecordVal(irc_join_info);
898 : 0 : string nick = users[i];
899 : 0 : string mode = "none";
900 : :
901 [ # # ]: 0 : if ( nick[0] == '@' )
902 : : {
903 [ # # ]: 0 : if ( nick[1] == '@' )
904 : : {
905 : 0 : nick = nick.substr(2);
906 : 0 : mode = "creator";
907 : : }
908 : : else
909 : : {
910 : 0 : nick = nick.substr(1);
911 : 0 : mode = "operator";
912 : : }
913 : : }
914 : :
915 [ # # ]: 0 : else if ( nick[0] == '+' )
916 : : {
917 : 0 : nick = nick.substr(1);
918 : 0 : mode = "voice";
919 : : }
920 : :
921 : 0 : info->Assign(0, new StringVal(nick.c_str()));
922 : 0 : info->Assign(1, new StringVal(channel.c_str()));
923 : : // Password:
924 : 0 : info->Assign(2, new StringVal(empty_string.c_str()));
925 : : // User mode:
926 : 0 : info->Assign(3, new StringVal(mode.c_str()));
927 : 0 : list->Assign(info, 0);
928 : 0 : Unref(info);
929 : : }
930 : :
931 : 0 : vl->append(list);
932 : :
933 [ # # ]: 0 : ConnectionEvent(irc_join_message, vl);
934 : : }
935 : :
936 [ # # ][ # # ]: 0 : else if ( irc_part_message && command == "PART" )
[ # # ]
937 : : {
938 : 0 : string channels = params;
939 : 0 : string message = "";
940 : 0 : unsigned int pos = params.find(' ');
941 : :
942 [ # # ]: 0 : if ( pos < params.size() )
943 : : {
944 : 0 : channels = params.substr(0, pos);
945 [ # # ]: 0 : if ( params.size() > pos + 1 )
946 : 0 : message = params.substr(pos + 1);
947 [ # # ]: 0 : if ( message[0] == ':' )
948 : 0 : message = message.substr(1);
949 : : }
950 : :
951 : 0 : string nick = prefix;
952 : 0 : pos = nick.find('!');
953 [ # # ]: 0 : if ( pos < nick.size() )
954 : 0 : nick = nick.substr(0, pos);
955 : :
956 : 0 : vector<string> channelList = SplitWords(channels, ',');
957 : 0 : TableVal* set = new TableVal(string_set);
958 : :
959 [ # # ]: 0 : for ( unsigned int i = 0; i < channelList.size(); ++i )
960 : : {
961 : 0 : Val* idx = new StringVal(channelList[i].c_str());
962 : 0 : set->Assign(idx, 0);
963 : 0 : Unref(idx);
964 : : }
965 : :
966 : 0 : val_list* vl = new val_list;
967 : 0 : vl->append(BuildConnVal());
968 : 0 : vl->append(new StringVal(nick.c_str()));
969 : 0 : vl->append(set);
970 : 0 : vl->append(new StringVal(message.c_str()));
971 : :
972 : 0 : ConnectionEvent(irc_part_message, vl);
973 : : }
974 : :
975 [ # # ][ # # ]: 0 : else if ( irc_quit_message && command == "QUIT" )
[ # # ]
976 : : {
977 : 0 : string message = params;
978 [ # # ]: 0 : if ( message[0] == ':' )
979 : 0 : message = message.substr(1);
980 : :
981 : 0 : string nickname = "";
982 [ # # ]: 0 : if ( prefix.size() > 0 )
983 : : {
984 : 0 : unsigned int pos = prefix.find('!');
985 [ # # ]: 0 : if ( pos < prefix.size() )
986 : 0 : nickname = prefix.substr(0, pos);
987 : : }
988 : :
989 : 0 : val_list* vl = new val_list;
990 : 0 : vl->append(BuildConnVal());
991 : 0 : vl->append(new StringVal(nickname.c_str()));
992 : 0 : vl->append(new StringVal(message.c_str()));
993 : :
994 : 0 : ConnectionEvent(irc_quit_message, vl);
995 : : }
996 : :
997 [ # # ][ # # ]: 0 : else if ( irc_nick_message && command == "NICK" )
[ # # ]
998 : : {
999 : 0 : string nick = params;
1000 [ # # ]: 0 : if ( nick[0] == ':' )
1001 : 0 : nick = nick.substr(1);
1002 : :
1003 : 0 : val_list* vl = new val_list;
1004 : 0 : vl->append(BuildConnVal());
1005 : 0 : vl->append(new StringVal(prefix.c_str()));
1006 : 0 : vl->append(new StringVal(nick.c_str()));
1007 : :
1008 : 0 : ConnectionEvent(irc_nick_message, vl);
1009 : : }
1010 : :
1011 [ # # ][ # # ]: 0 : else if ( irc_who_message && command == "WHO" )
[ # # ]
1012 : : {
1013 : 0 : vector<string> parts = SplitWords(params, ' ');
1014 [ # # # # ]: 0 : if ( parts.size() < 1 || parts.size() > 2 )
[ # # ]
1015 : : {
1016 : 0 : Weird("irc_invalid_who_message_format");
1017 : : return;
1018 : : }
1019 : :
1020 : 0 : bool oper = false;
1021 [ # # ][ # # ]: 0 : if ( parts.size() == 2 && parts[1] == "o" )
[ # # ]
1022 : 0 : oper = true;
1023 : :
1024 : : // Remove ":" from mask.
1025 [ # # ][ # # ]: 0 : if ( parts[0].size() > 0 && parts[0][0] == ':' )
[ # # ]
1026 : 0 : parts[0] = parts[0].substr(1);
1027 : :
1028 : 0 : val_list* vl = new val_list;
1029 : 0 : vl->append(BuildConnVal());
1030 : 0 : vl->append(new StringVal(parts[0].c_str()));
1031 : 0 : vl->append(new Val(oper, TYPE_BOOL));
1032 : :
1033 [ # # ]: 0 : ConnectionEvent(irc_who_message, vl);
1034 : : }
1035 : :
1036 [ # # ][ # # ]: 0 : else if ( irc_whois_message && command == "WHOIS" )
[ # # ]
1037 : : {
1038 : 0 : vector<string> parts = SplitWords(params, ' ');
1039 [ # # # # ]: 0 : if ( parts.size() < 1 || parts.size() > 2 )
[ # # ]
1040 : : {
1041 : 0 : Weird("irc_invalid_whois_message_format");
1042 : : return;
1043 : : }
1044 : :
1045 : 0 : string server = "";
1046 : 0 : string users = "";
1047 : :
1048 [ # # ]: 0 : if ( parts.size() == 2 )
1049 : : {
1050 : 0 : server = parts[0];
1051 : 0 : users = parts[1];
1052 : : }
1053 : : else
1054 : 0 : users = parts[0];
1055 : :
1056 : 0 : val_list* vl = new val_list;
1057 : 0 : vl->append(BuildConnVal());
1058 : 0 : vl->append(new StringVal(server.c_str()));
1059 : 0 : vl->append(new StringVal(users.c_str()));
1060 : :
1061 [ # # ]: 0 : ConnectionEvent(irc_whois_message, vl);
1062 : : }
1063 : :
1064 [ # # ][ # # ]: 0 : else if ( irc_error_message && command == "ERROR" )
[ # # ]
1065 : : {
1066 : 0 : val_list* vl = new val_list;
1067 : 0 : vl->append(BuildConnVal());
1068 : 0 : vl->append(new StringVal(prefix.c_str()));
1069 [ # # ]: 0 : if ( params[0] == ':' )
1070 : 0 : params = params.substr(1);
1071 : 0 : vl->append(new StringVal(params.c_str()));
1072 : :
1073 : 0 : ConnectionEvent(irc_error_message, vl);
1074 : : }
1075 : :
1076 [ # # ][ # # ]: 0 : else if ( irc_invite_message && command == "INVITE" )
[ # # ]
1077 : : {
1078 : 0 : vector<string> parts = SplitWords(params, ' ');
1079 [ # # ]: 0 : if ( parts.size() == 2 )
1080 : : { // remove ":" from channel
1081 [ # # ][ # # ]: 0 : if ( parts[1].size() > 0 && parts[1][0] == ':' )
[ # # ]
1082 : 0 : parts[1] = parts[1].substr(1);
1083 : :
1084 : 0 : val_list* vl = new val_list;
1085 : 0 : vl->append(BuildConnVal());
1086 : 0 : vl->append(new StringVal(prefix.c_str()));
1087 : 0 : vl->append(new StringVal(parts[0].c_str()));
1088 : 0 : vl->append(new StringVal(parts[1].c_str()));
1089 : :
1090 : 0 : ConnectionEvent(irc_invite_message, vl);
1091 : : }
1092 : : else
1093 : 0 : Weird("irc_invalid_invite_message_format");
1094 : : }
1095 : :
1096 [ # # ][ # # ]: 0 : else if ( irc_mode_message && command == "MODE" )
[ # # ]
1097 : : {
1098 [ # # ]: 0 : if ( params.size() > 0 )
1099 : : {
1100 : 0 : val_list* vl = new val_list;
1101 : 0 : vl->append(BuildConnVal());
1102 : 0 : vl->append(new StringVal(prefix.c_str()));
1103 : 0 : vl->append(new StringVal(params.c_str()));
1104 : :
1105 : 0 : ConnectionEvent(irc_mode_message, vl);
1106 : : }
1107 : :
1108 : : else
1109 : 0 : Weird("irc_invalid_mode_message_format");
1110 : : }
1111 : :
1112 [ # # ][ # # ]: 0 : else if ( irc_password_message && command == "PASS" )
[ # # ]
1113 : : {
1114 : 0 : val_list* vl = new val_list;
1115 : 0 : vl->append(BuildConnVal());
1116 : 0 : vl->append(new StringVal(params.c_str()));
1117 : 0 : ConnectionEvent(irc_password_message, vl);
1118 : : }
1119 : :
1120 [ # # ][ # # ]: 0 : else if ( irc_squit_message && command == "SQUIT" )
[ # # ]
1121 : : {
1122 : 0 : string server = params;
1123 : 0 : string message = "";
1124 : :
1125 : 0 : unsigned int pos = params.find(' ');
1126 [ # # ]: 0 : if ( pos < params.size() )
1127 : : {
1128 : 0 : server = params.substr(0, pos);
1129 : 0 : message = params.substr(pos + 1);
1130 [ # # ]: 0 : if ( message[0] == ':' )
1131 : 0 : message = message.substr(1);
1132 : : }
1133 : :
1134 : 0 : val_list* vl = new val_list;
1135 : 0 : vl->append(BuildConnVal());
1136 : 0 : vl->append(new StringVal(prefix.c_str()));
1137 : 0 : vl->append(new StringVal(server.c_str()));
1138 : 0 : vl->append(new StringVal(message.c_str()));
1139 : :
1140 : 0 : ConnectionEvent(irc_squit_message, vl);
1141 : : }
1142 : :
1143 : :
1144 [ # # ]: 0 : else if ( orig )
1145 : : {
1146 [ # # ]: 0 : if ( irc_request )
1147 : : {
1148 : 0 : val_list* vl = new val_list;
1149 : 0 : vl->append(BuildConnVal());
1150 : 0 : vl->append(new StringVal(prefix.c_str()));
1151 : 0 : vl->append(new StringVal(command.c_str()));
1152 : 0 : vl->append(new StringVal(params.c_str()));
1153 : :
1154 : 0 : ConnectionEvent(irc_request, vl);
1155 : : }
1156 : : }
1157 : :
1158 : : else
1159 : : {
1160 [ # # ]: 0 : if ( irc_message )
1161 : : {
1162 : 0 : val_list* vl = new val_list;
1163 : 0 : vl->append(BuildConnVal());
1164 : 0 : vl->append(new StringVal(prefix.c_str()));
1165 : 0 : vl->append(new StringVal(command.c_str()));
1166 : 0 : vl->append(new StringVal(params.c_str()));
1167 : :
1168 : 0 : ConnectionEvent(irc_message, vl);
1169 : : }
1170 : : }
1171 : :
1172 [ # # ][ # # ]: 0 : if ( orig_status == REGISTERED && resp_status == REGISTERED &&
[ # # ][ # # ]
1173 : : orig_zip_status == ACCEPT_ZIP && resp_zip_status == ACCEPT_ZIP )
1174 : : {
1175 : : #ifdef HAVE_LIBZ
1176 : 0 : orig_zip_status = ZIP_LOADED;
1177 : 0 : resp_zip_status = ZIP_LOADED;
1178 : 0 : AddSupportAnalyzer(new ZIP_Analyzer(Conn(), true));
1179 : 0 : AddSupportAnalyzer(new ZIP_Analyzer(Conn(), false));
1180 : : #else
1181 : : run_time("IRC analyzer lacking libz support");
1182 : : Remove();
1183 : : #endif
1184 : : }
1185 : :
1186 : 0 : return;
1187 : : }
1188 : :
1189 : 0 : vector<string> IRC_Analyzer::SplitWords(const string input, const char split)
1190 : : {
1191 : 0 : vector<string> words;
1192 : :
1193 [ # # ]: 0 : if ( input.size() < 1 )
1194 : 0 : return words;
1195 : :
1196 : 0 : unsigned int start = 0;
1197 : 0 : unsigned int split_pos = 0;
1198 : :
1199 : : // Ignore split-characters at the line beginning.
1200 [ # # ]: 0 : while ( input[start] == split )
1201 : : {
1202 : 0 : ++start;
1203 : 0 : ++split_pos;
1204 : : }
1205 : :
1206 : 0 : string word = "";
1207 [ # # ]: 0 : while ( (split_pos = input.find(split, start)) < input.size() )
1208 : : {
1209 : 0 : word = input.substr(start, split_pos - start);
1210 [ # # # # ]: 0 : if ( word.size() > 0 && word[0] != split )
[ # # ]
1211 : 0 : words.push_back(word);
1212 : :
1213 : 0 : start = split_pos + 1;
1214 : : }
1215 : :
1216 : : // Add line end if needed.
1217 [ # # ]: 0 : if ( start < input.size() )
1218 : : {
1219 : 0 : word = input.substr(start, input.size() - start);
1220 : 0 : words.push_back(word);
1221 : : }
1222 : :
1223 : 0 : return words;
1224 [ + - ][ + - ]: 6 : }
|