File Coverage

blib/lib/AOL/TOC.pm
Criterion Covered Total %
statement 9 236 3.8
branch 0 56 0.0
condition 0 27 0.0
subroutine 3 42 7.1
pod 8 38 21.0
total 20 399 5.0


line stmt bran cond sub pod time code
1             package AOL::TOC;
2              
3 1     1   1465 use IO;
  1         875  
  1         6  
4 1     1   105673 use Socket;
  1         2  
  1         1043  
5 1     1   905 use AOL::SFLAP;
  1         3  
  1         3943  
6              
7             $VERSION = "0.34";
8             $TOC_VERSION = "1.0";
9             $ROASTING_KEY = "Tic/Toc";
10              
11             # Preloaded methods go here.
12              
13             # Autoload methods go after =cut, and are processed by the autosplit program.
14              
15             =head1 NAME
16              
17             AOL::TOC - Perl extension for interfacing with AOL's AIM service
18              
19             =head1 SYNOPSIS
20              
21             use AOL::TOC;
22             $toc = AOL::TOC::new($toc_server, $login_server, $port,
23             $screenname, $password);
24             $toc->connect();
25              
26             =head1 DESCRIPTION
27              
28             This module implements SFLAP, which I presume to be AOL's authenticiation
29             protocol, and TOC, which is the actual "meat" of the AIM protocol.
30              
31             =head1 INTERFACE
32              
33             =head2 connect
34              
35             connects to the AIM server
36              
37             =head2 register_callback
38              
39             This function takes two arguments, the EVENT and the subroutine reference.
40             Callbacks are similar to the ones found in Net::IRC. The module defines
41             several AIM "events": ERROR, CLOSED, SIGN_ON, IM_IN, CHAT_IN, UPDATE_BUDDY.
42             These events can be bound to subroutines.
43              
44             =head2 dispatch
45              
46             This flushes all messages to the server, and retreives all current messages.
47              
48             =head2 add_buddy
49              
50             Takes one arguement, the nick of the buddy.
51             This adds a buddy to your buddy list.
52              
53             =head2 send_im
54              
55             Takes two arguments, the name of the buddy and the name of the message, and
56             sends the IM.
57              
58             =head2 get_info
59              
60             Takes one argument, the name of the buddy, and returns the info.
61              
62             =head2 chat_join
63              
64             Takes one argument, the name of the chat room to join
65              
66             =head2 chat_send
67              
68             Takes two arguments, the name of the chat room, and the message.
69              
70             =head1 AUTHOR
71              
72             xjharding@newbedford.k12.ma.us cleaned it up and added DOC
73             james@foo.org was the original author
74              
75             =head1 SEE ALSO
76              
77             Net::AIM, a new module, but it doesn't have the features of this one
78              
79             =cut
80              
81             sub roast_password {
82 0     0 0   my ($password, $key) = @_;
83 0           my @skey;
84 0           my $rpassword = "0x";
85 0           my $i = 0;
86              
87 0 0         if (!$key) { $key = $ROASTING_KEY; }
  0            
88              
89 0           @skey = split('', $key);
90              
91 0           for $c (split('', $password)) {
92 0           $p = unpack("c", $c);
93 0           $k = unpack("c", @skey[$i % length($key)]);
94 0           $rpassword = sprintf("%s%02x", $rpassword, $p ^ $k);
95 0           $i ++;
96             }
97              
98 0           return ($rpassword);
99             }
100              
101              
102             sub encode_string {
103 0     0 0   my ($self, $str) = @_;
104 0           my ($estr, $i);
105              
106 0 0         if (!$str) { $str = $self; }
  0            
107              
108 0           $estr = "\"";
109 0           for $i (split('', $str)) {
110 0 0 0       if (
      0        
      0        
      0        
      0        
      0        
      0        
      0        
111             ($i eq "\\") || ($i eq "\{") || ($i eq "\}") ||
112             ($i eq "\(") || ($i eq "\)") || ($i eq "\[") ||
113             ($i eq "\]") || ($i eq "\$") || ($i eq "\""))
114             {
115 0           $estr .= "\\";
116             }
117 0           $estr .= $i;
118             }
119 0           $estr .= "\"";
120              
121 0           return ($estr);
122             }
123              
124              
125             sub register_callback {
126 0     0 1   my ($self, $event, $func, @args) = @_;
127              
128 0           push (@{$self->{callback}{$event}}, $func);
  0            
129 0           @{$self->{callback}{$func}} = @args;
  0            
130              
131 0           return;
132             }
133              
134              
135             sub callback {
136 0     0 0   my ($self, $event, @args) = @_;
137 0           my $func;
138              
139 0           for $func (@{$self->{callback}{$event}}) {
  0            
140 0           eval { &{$func} ($self, @args, @{$self->{callback}{$func}}) };
  0            
  0            
  0            
141             }
142              
143 0           return;
144             }
145              
146              
147             sub clear_callbacks {
148 0     0 0   my ($self) = @_;
149 0           my $k;
150            
151 0           print "................ TOC clear_callbacks\n";
152 0           for $k (keys %{$self->{callback}}) {
  0            
153 0           print ".............. Clear key ($k)\n";
154 0           delete $self->{callback}{$k};
155             }
156              
157 0           print "...............S TOC scan callbacks\n";
158 0           for $k (keys %{$self->{callback}}) {
  0            
159 0           print ".............S Scan key ($k)\n";
160             }
161             }
162              
163              
164             sub new {
165 0     0 0   my ($tochost, $authorizer, $port, $nickname, $password) = @_;
166 0           my ($self, $ipaddr, $sflap);
167              
168 0           $self = {
169             nickname => $nickname,
170             password => $password,
171             caller => "file:line"
172             };
173            
174 0           bless($self);
175              
176 0           $sflap = AOL::SFLAP::new($tochost, $authorizer, $port, $nickname);
177 0           $self->{sflap} = $sflap;
178              
179             #print "*************************** AOL::TOC::new(...) sflap = $self->{sflap}\n";
180             #print " sflap cb = $self->{sflap}{callback}\n";
181              
182             #$self->{sflap}->register_callback($AOL::SFLAP::SFLAP_SIGNON, \&sflap_signon, $password, "english", "TIK:\$Revision: 1.148 \$", $self);
183             #$self->{sflap}->register_callback($AOL::SFLAP::SFLAP_DATA, \&sflap_data, $self);
184             #$self->{sflap}->register_callback($AOL::SFLAP::SFLAP_ERROR, \&sflap_error, $self);
185             #$self->{sflap}->register_callback($AOL::SFLAP::SFLAP_SIGNOFF, \&sflap_signoff, $self);
186             #$self->{sflap}->register_callback($AOL::SFLAP::SFLAP_KEEPALIVE, \&sflap_keepalive, $self);
187             #
188             #$self->register_callback("SIGN_ON", \&check_version);
189             #$self->register_callback("CHAT_JOIN", \&_chat_join);
190              
191 0           return $self;
192             }
193              
194              
195             sub destroy {
196 0     0 0   my ($self) = @_;
197            
198 0           print "toc destroy\n";
199 0           $self->{sflap}->destroy();
200              
201 0           $self->{callback} = undef;
202 0           $self = undef;
203              
204 0           return;
205             }
206              
207              
208             sub set_debug {
209 0     0 0   my ($self, $level) = @_;
210              
211 0           $self->{sflap}->set_debug($level);
212             }
213              
214              
215             sub debug {
216 0     0 0   my ($self, @args) = @_;
217              
218 0 0         if ($self->{debug_level} > 0) {
219 0           print @args;
220             }
221             }
222              
223              
224             sub connect {
225 0     0 1   my ($self) = @_;
226              
227 0           $self->{sflap}->register_callback($AOL::SFLAP::SFLAP_SIGNON, \&sflap_signon, $self->{password}, "english", "TIK:\$Revision: 1.148 \$", $self);
228 0           $self->{sflap}->register_callback($AOL::SFLAP::SFLAP_DATA, \&sflap_data, $self);
229 0           $self->{sflap}->register_callback($AOL::SFLAP::SFLAP_ERROR, \&sflap_error, $self);
230 0           $self->{sflap}->register_callback($AOL::SFLAP::SFLAP_SIGNOFF, \&sflap_signoff, $self);
231 0           $self->{sflap}->register_callback($AOL::SFLAP::SFLAP_KEEPALIVE, \&sflap_keepalive, $self);
232            
233 0           $self->register_callback("SIGN_ON", \&check_version);
234 0           $self->register_callback("CHAT_JOIN", \&_chat_join);
235              
236 0           $self->{sflap}->connect();
237             }
238              
239             sub close {
240 0     0 0   my ($self) = @_;
241 0           my $k;
242              
243 0           $self->clear_callbacks();
244 0           $self->{sflap}->close();
245             }
246              
247              
248             sub check_version {
249 0     0 0   my ($self, $version) = @_;
250              
251 0 0         if ($version > $TOC_VERSION) {
252 0           $self->destroy();
253             }
254              
255 0           $self->init_done();
256              
257 0           return;
258             }
259              
260              
261             sub send {
262 0     0 0   my ($self, $data) = @_;
263              
264 0           $self->{sflap}->send($AOL::SFLAP::SFLAP_DATA, $data);
265             }
266              
267              
268             sub dispatch {
269 0     0 1   my ($self) = @_;
270              
271 0           $self->{sflap}->recv();
272             }
273              
274              
275             # Utilities
276              
277             sub signon {
278 0     0 0   my ($self, $authorizer, $port, $nickname, $roasted_password, $language, $version) = @_;
279              
280 0           $self->send("toc_signon $authorizer $port $nickname $roasted_password $language " . &encode_string($version));
281 0           return;
282             }
283              
284             sub init_done {
285 0     0 0   my ($self) = @_;
286              
287 0           $self->send("toc_init_done");
288 0           return;
289             }
290              
291              
292             sub send_im {
293 0     0 1   my ($self, $nickname, $message, $auto) = @_;
294              
295 0 0         $auto = "" unless defined $auto;
296              
297 0           $self->send("toc_send_im $nickname " . &encode_string($message) . " $auto");
298 0           return;
299             }
300              
301              
302             sub add_buddy {
303 0     0 1   my ($self, @buddies) = @_;
304              
305 0           $self->send("toc_add_buddy @buddies");
306 0           return;
307             }
308              
309              
310             sub remove_buddy {
311 0     0 0   my ($self, @buddies) = @_;
312              
313 0           $self->send("toc_remove_buddy @buddies");
314 0           return;
315             }
316              
317              
318             sub set_config {
319 0     0 0   my ($self, $config) = @_;
320              
321 0           $self->send("toc_set_config $config");
322 0           return;
323             }
324              
325              
326             sub evil {
327 0     0 0   my ($self, $nickname, $mode) = @_;
328              
329 0           $self->send("toc_evil $nickname $mode\n");
330 0           return;
331             }
332              
333              
334             sub add_permit {
335 0     0 0   my ($self, @buddies) = @_;
336              
337 0           $self->send("toc_add_permit @buddies");
338 0           return;
339             }
340              
341              
342             sub add_deny {
343 0     0 0   my ($self, @buddies) = @_;
344              
345 0           $self->send("toc_add_deny @buddies");
346 0           return;
347             }
348              
349              
350             sub chat_join {
351 0     0 1   my $self = shift;
352 0           my $exchange = shift;
353 0           my $room;
354            
355 0 0         if ($exchange =~ /\D/) {
356 0           $room = $exchange;
357 0           $exchange = 4;
358             } else {
359 0           $room = shift;
360             }
361              
362 0           $self->send("toc_chat_join $exchange " . &encode_string($room));
363 0           return;
364             }
365              
366              
367             sub _chat_join {
368 0     0     my ($self, $room_id, $room_name) = @_;
369              
370 0           $self->{chatrooms}{$room_id} = $room_name;
371 0           $self->{chatrooms}{$room_name} = $room_id;
372 0           return;
373             }
374              
375              
376             sub chat_send {
377 0     0 1   my ($self, $room_id, $message) = @_;
378              
379 0 0         if ($room_id =~ /\D/) {
380 0           $room_id = $self->{chatrooms}{$room_id};
381             }
382              
383 0           $self->send("toc_chat_send $room_id " . &encode_string($message));
384 0           return;
385             }
386              
387              
388             sub chat_whisper {
389 0     0 0   my ($self, $room_id, $nickname, $message) = @_;
390            
391 0 0         if ($room_id =~ /\D/) {
392 0           $room_id = $self->{chatrooms}{$room_id};
393             }
394              
395 0           $self->send("toc_chat_whisper $room_id $nickname " . &encode_string($message));
396 0           return;
397             }
398              
399              
400             sub chat_evil {
401 0     0 0   my ($self, $room_id, $nickname, $mode) = @_;
402            
403 0 0         if ($room_id =~ /\D/) {
404 0           $room_id = $self->{chatrooms}{$room_id};
405             }
406              
407 0           $self->send("toc_chat_evil $room_id $nickname $mode");
408 0           return;
409             }
410              
411              
412             sub chat_invite {
413 0     0 0   my ($self, $room_id, $message, @buddies) = @_;
414            
415 0 0         if ($room_id =~ /\D/) {
416 0           $room_id = $self->{chatrooms}{$room_id};
417             }
418              
419 0           $self->send("toc_chat_invite $room_id " . &encode_string($message) . " @buddies");
420 0           return;
421             }
422              
423              
424             sub chat_leave {
425 0     0 0   my ($self, $room_id) = @_;
426              
427 0 0         if ($room_id =~ /\D/) {
428 0           $room_id = $self->{chatrooms}{$room_id};
429             }
430            
431 0           $self->send("toc_chat_leave $room_id");
432 0           return;
433             }
434              
435              
436             sub chat_accept {
437 0     0 0   my ($self, $room_id) = @_;
438              
439 0 0         if ($room_id =~ /\D/) {
440 0           $room_id = $self->{chatrooms}{$room_id};
441             }
442              
443 0           $self->send("toc_chat_accept $room_id");
444 0           return;
445             }
446              
447              
448             sub get_info {
449 0     0 1   my ($self, $nickname) = @_;
450              
451 0           $self->send("toc_get_info $nickname");
452 0           return;
453             }
454              
455              
456             sub set_info {
457 0     0 0   my ($self, $info) = @_;
458              
459 0           $self->send("toc_set_info " . &encode_string($info));
460 0           return;
461             }
462              
463              
464             # SFLAP Callbacks
465              
466             sub sflap_signon {
467 0     0 0   my ($self, $data, $password, $language, $version, $toc) = @_;
468 0           my ($buffer, $roasted_password);
469              
470 0           $roasted_password = roast_password($password, $ROASTING_KEY);
471              
472 0           $buffer = pack("Nnna*", 1, 1, length($toc->{sflap}->{nickname}), $toc->{sflap}->{nickname});
473 0           $toc->{sflap}->send($AOL::SFLAP::SFLAP_SIGNON, $buffer);
474              
475 0           $toc->signon($toc->{sflap}->{authorizer}, $toc->{sflap}->{port}, $toc->{sflap}->{nickname}, $roasted_password, $language, $version);
476             }
477              
478             sub sflap_data {
479 0     0 0   my ($self, $data, $toc) = @_;
480 0           my ($cmd, $args);
481              
482 0           ($cmd, $args) = ($data =~ /^(\w+)\:(.*)$/);
483              
484 0 0 0       return unless defined $cmd && defined $args;
485              
486 0 0         if ($cmd eq "SIGN_ON") {
487 0           ($toc_version) = ($args =~ /^TOC(.*)$/);
488 0           $toc->callback("SIGN_ON", $toc_version);
489             }
490              
491 0 0         if ($cmd eq "CONFIG") {
492 0           $toc->callback("CONFIG", $args);
493             }
494              
495 0 0         if ($cmd eq "NICK") {
496 0           ($beautified_nick) = ($args =~ /^(.*)$/);
497 0           $toc->callback("NICK", $beautified_nick);
498             }
499              
500 0 0         if ($cmd eq "IM_IN") {
501 0           ($nickname, $autoresponse, $message) = ($args =~ /^(.*)\:(.*)\:(.*)$/);
502 0           $toc->callback("IM_IN", $nickname, $autoresponse, $message);
503             }
504              
505 0 0         if ($cmd eq "UPDATE_BUDDY") {
506 0           ($nickname, $online, $evil, $signon_time, $idle_time, $class) = ($args =~ /^(.*)\:(.*)\:(.*)\:(.*)\:(.*)\:(.*)$/);
507 0           $toc->callback("UPDATE_BUDDY", $nickname, $online, $evil, $signon_time, $idle_Time, $class);
508             }
509              
510 0 0         if ($cmd eq "ERROR") {
511 0           ($code, $args) = ($args =~ /^(\d*).?(.*)$/);
512 0           $toc->callback("ERROR", $code, $args);
513             }
514              
515 0 0         if ($cmd eq "EVILED") {
516 0           ($evil_level, $nickname) = ($args =~ /^(.*)\:(.*)$/);
517 0           $toc->callback("EVILED", $evil_level, $nickname);
518             }
519              
520 0 0         if ($cmd eq "CHAT_JOIN") {
521 0           ($room_id, $room_name) = ($args =~ /^(.*)\:(.*)$/);
522 0           $toc->callback("CHAT_JOIN", $room_id, $room_name);
523             }
524              
525 0 0         if ($cmd eq "CHAT_IN") {
526 0           ($room_id, $nickname, $whisper, $message) = ($args =~ /^(.*)\:(.*)\:(.*)\:(.*)$/);
527 0           $toc->callback("CHAT_IN", $room_id, $nickname, $whisper, $message);
528             }
529              
530 0 0         if ($cmd eq "CHAT_UPDATE_BUDDY") {
531 0           ($room_id, $inside, $nicknames) = ($args =~ /^(.*)\:(.*)\:(.*)$/);
532 0           $toc->callback("CHAT_UPDATE_BUDDY", $room_id, $inside, $nicknames);
533             }
534              
535 0 0         if ($cmd eq "CHAT_INVITE") {
536 0           ($room_name, $room_id, $nickname, $message) = ($args =~ /^(.*)\:(.*)\:(.*)\:(.*)$/);
537 0           $toc->callback("CHAT_INVITE", $room_name, $room_id, $nickname, $message);
538             }
539              
540 0 0         if ($cmd eq "CHAT_LEFT") {
541 0           ($room_id) = ($args =~ /^(.*)$/);
542 0           $toc->callback("CHAT_LEFT", $room_id);
543             }
544              
545 0 0         if ($cmd eq "GOTO_URL") {
546 0           ($window_name, $url) = ($args =~ /^(.*)\:(.*)$/);
547 0           $toc->callback("GOTO_URL", $window_name, $url);
548             }
549              
550 0 0         if ($cmd eq "PAUSE") {
551 0           $toc->callback("PAUSE");
552             }
553              
554             }
555              
556             sub sflap_error {
557 0     0 0   my ($self, $data, $toc) = @_;
558              
559 0           return;
560             }
561              
562             sub sflap_signoff {
563 0     0 0   my ($self, $data, $toc) = @_;
564              
565 0           $toc->callback("CLOSED");
566              
567             #foreach $k (keys %{$toc->{callback}}) {
568             # print "Deleting .. $k\n";
569             # delete $toc->{callback}{$k};
570             #}
571              
572 0           $toc->destroy();
573              
574 0           return;
575             }
576              
577             sub test {
578 0     0 0   my ($self) = @_;
579              
580 0           return \&test($self);
581             }
582              
583             sub send_signoff {
584 0     0 0   my ($self) = @_;
585              
586 0           $self->{sflap}->send($AOL::SFLAP::SFLAP_SIGNOFF, "");
587             }
588              
589             1;
590             __END__