| AOL-TOC documentation | Contained in the AOL-TOC distribution. |
AOL::TOC - Perl extension for interfacing with AOL's AIM service
use AOL::TOC;
$toc = AOL::TOC::new($toc_server, $login_server, $port,
$screenname, $password);
$toc->connect();
This module implements SFLAP, which I presume to be AOL's authenticiation protocol, and TOC, which is the actual "meat" of the AIM protocol.
connects to the AIM server
This function takes two arguments, the EVENT and the subroutine reference. Callbacks are similar to the ones found in Net::IRC. The module defines several AIM "events": ERROR, CLOSED, SIGN_ON, IM_IN, CHAT_IN, UPDATE_BUDDY. These events can be bound to subroutines.
This flushes all messages to the server, and retreives all current messages.
Takes one arguement, the nick of the buddy. This adds a buddy to your buddy list.
Takes two arguments, the name of the buddy and the name of the message, and sends the IM.
Takes one argument, the name of the buddy, and returns the info.
Takes one argument, the name of the chat room to join
Takes two arguments, the name of the chat room, and the message.
xjharding@newbedford.k12.ma.us cleaned it up and added DOC james@foo.org was the original author
Net::AIM, a new module, but it doesn't have the features of this one
| AOL-TOC documentation | Contained in the AOL-TOC distribution. |
package AOL::TOC; use IO; use Socket; use AOL::SFLAP; $VERSION = "0.34"; $TOC_VERSION = "1.0"; $ROASTING_KEY = "Tic/Toc"; # Preloaded methods go here. # Autoload methods go after =cut, and are processed by the autosplit program.
sub roast_password { my ($password, $key) = @_; my @skey; my $rpassword = "0x"; my $i = 0; if (!$key) { $key = $ROASTING_KEY; } @skey = split('', $key); for $c (split('', $password)) { $p = unpack("c", $c); $k = unpack("c", @skey[$i % length($key)]); $rpassword = sprintf("%s%02x", $rpassword, $p ^ $k); $i ++; } return ($rpassword); } sub encode_string { my ($self, $str) = @_; my ($estr, $i); if (!$str) { $str = $self; } $estr = "\""; for $i (split('', $str)) { if ( ($i eq "\\") || ($i eq "\{") || ($i eq "\}") || ($i eq "\(") || ($i eq "\)") || ($i eq "\[") || ($i eq "\]") || ($i eq "\$") || ($i eq "\"")) { $estr .= "\\"; } $estr .= $i; } $estr .= "\""; return ($estr); } sub register_callback { my ($self, $event, $func, @args) = @_; push (@{$self->{callback}{$event}}, $func); @{$self->{callback}{$func}} = @args; return; } sub callback { my ($self, $event, @args) = @_; my $func; for $func (@{$self->{callback}{$event}}) { eval { &{$func} ($self, @args, @{$self->{callback}{$func}}) }; } return; } sub clear_callbacks { my ($self) = @_; my $k; print "................ TOC clear_callbacks\n"; for $k (keys %{$self->{callback}}) { print ".............. Clear key ($k)\n"; delete $self->{callback}{$k}; } print "...............S TOC scan callbacks\n"; for $k (keys %{$self->{callback}}) { print ".............S Scan key ($k)\n"; } } sub new { my ($tochost, $authorizer, $port, $nickname, $password) = @_; my ($self, $ipaddr, $sflap); $self = { nickname => $nickname, password => $password, caller => "file:line" }; bless($self); $sflap = AOL::SFLAP::new($tochost, $authorizer, $port, $nickname); $self->{sflap} = $sflap; #print "*************************** AOL::TOC::new(...) sflap = $self->{sflap}\n"; #print " sflap cb = $self->{sflap}{callback}\n"; #$self->{sflap}->register_callback($AOL::SFLAP::SFLAP_SIGNON, \&sflap_signon, $password, "english", "TIK:\$Revision: 1.148 \$", $self); #$self->{sflap}->register_callback($AOL::SFLAP::SFLAP_DATA, \&sflap_data, $self); #$self->{sflap}->register_callback($AOL::SFLAP::SFLAP_ERROR, \&sflap_error, $self); #$self->{sflap}->register_callback($AOL::SFLAP::SFLAP_SIGNOFF, \&sflap_signoff, $self); #$self->{sflap}->register_callback($AOL::SFLAP::SFLAP_KEEPALIVE, \&sflap_keepalive, $self); # #$self->register_callback("SIGN_ON", \&check_version); #$self->register_callback("CHAT_JOIN", \&_chat_join); return $self; } sub destroy { my ($self) = @_; print "toc destroy\n"; $self->{sflap}->destroy(); $self->{callback} = undef; $self = undef; return; } sub set_debug { my ($self, $level) = @_; $self->{sflap}->set_debug($level); } sub debug { my ($self, @args) = @_; if ($self->{debug_level} > 0) { print @args; } } sub connect { my ($self) = @_; $self->{sflap}->register_callback($AOL::SFLAP::SFLAP_SIGNON, \&sflap_signon, $self->{password}, "english", "TIK:\$Revision: 1.148 \$", $self); $self->{sflap}->register_callback($AOL::SFLAP::SFLAP_DATA, \&sflap_data, $self); $self->{sflap}->register_callback($AOL::SFLAP::SFLAP_ERROR, \&sflap_error, $self); $self->{sflap}->register_callback($AOL::SFLAP::SFLAP_SIGNOFF, \&sflap_signoff, $self); $self->{sflap}->register_callback($AOL::SFLAP::SFLAP_KEEPALIVE, \&sflap_keepalive, $self); $self->register_callback("SIGN_ON", \&check_version); $self->register_callback("CHAT_JOIN", \&_chat_join); $self->{sflap}->connect(); } sub close { my ($self) = @_; my $k; $self->clear_callbacks(); $self->{sflap}->close(); } sub check_version { my ($self, $version) = @_; if ($version > $TOC_VERSION) { $self->destroy(); } $self->init_done(); return; } sub send { my ($self, $data) = @_; $self->{sflap}->send($AOL::SFLAP::SFLAP_DATA, $data); } sub dispatch { my ($self) = @_; $self->{sflap}->recv(); } # Utilities sub signon { my ($self, $authorizer, $port, $nickname, $roasted_password, $language, $version) = @_; $self->send("toc_signon $authorizer $port $nickname $roasted_password $language " . &encode_string($version)); return; } sub init_done { my ($self) = @_; $self->send("toc_init_done"); return; } sub send_im { my ($self, $nickname, $message, $auto) = @_; $auto = "" unless defined $auto; $self->send("toc_send_im $nickname " . &encode_string($message) . " $auto"); return; } sub add_buddy { my ($self, @buddies) = @_; $self->send("toc_add_buddy @buddies"); return; } sub remove_buddy { my ($self, @buddies) = @_; $self->send("toc_remove_buddy @buddies"); return; } sub set_config { my ($self, $config) = @_; $self->send("toc_set_config $config"); return; } sub evil { my ($self, $nickname, $mode) = @_; $self->send("toc_evil $nickname $mode\n"); return; } sub add_permit { my ($self, @buddies) = @_; $self->send("toc_add_permit @buddies"); return; } sub add_deny { my ($self, @buddies) = @_; $self->send("toc_add_deny @buddies"); return; } sub chat_join { my $self = shift; my $exchange = shift; my $room; if ($exchange =~ /\D/) { $room = $exchange; $exchange = 4; } else { $room = shift; } $self->send("toc_chat_join $exchange " . &encode_string($room)); return; } sub _chat_join { my ($self, $room_id, $room_name) = @_; $self->{chatrooms}{$room_id} = $room_name; $self->{chatrooms}{$room_name} = $room_id; return; } sub chat_send { my ($self, $room_id, $message) = @_; if ($room_id =~ /\D/) { $room_id = $self->{chatrooms}{$room_id}; } $self->send("toc_chat_send $room_id " . &encode_string($message)); return; } sub chat_whisper { my ($self, $room_id, $nickname, $message) = @_; if ($room_id =~ /\D/) { $room_id = $self->{chatrooms}{$room_id}; } $self->send("toc_chat_whisper $room_id $nickname " . &encode_string($message)); return; } sub chat_evil { my ($self, $room_id, $nickname, $mode) = @_; if ($room_id =~ /\D/) { $room_id = $self->{chatrooms}{$room_id}; } $self->send("toc_chat_evil $room_id $nickname $mode"); return; } sub chat_invite { my ($self, $room_id, $message, @buddies) = @_; if ($room_id =~ /\D/) { $room_id = $self->{chatrooms}{$room_id}; } $self->send("toc_chat_invite $room_id " . &encode_string($message) . " @buddies"); return; } sub chat_leave { my ($self, $room_id) = @_; if ($room_id =~ /\D/) { $room_id = $self->{chatrooms}{$room_id}; } $self->send("toc_chat_leave $room_id"); return; } sub chat_accept { my ($self, $room_id) = @_; if ($room_id =~ /\D/) { $room_id = $self->{chatrooms}{$room_id}; } $self->send("toc_chat_accept $room_id"); return; } sub get_info { my ($self, $nickname) = @_; $self->send("toc_get_info $nickname"); return; } sub set_info { my ($self, $info) = @_; $self->send("toc_set_info " . &encode_string($info)); return; } # SFLAP Callbacks sub sflap_signon { my ($self, $data, $password, $language, $version, $toc) = @_; my ($buffer, $roasted_password); $roasted_password = roast_password($password, $ROASTING_KEY); $buffer = pack("Nnna*", 1, 1, length($toc->{sflap}->{nickname}), $toc->{sflap}->{nickname}); $toc->{sflap}->send($AOL::SFLAP::SFLAP_SIGNON, $buffer); $toc->signon($toc->{sflap}->{authorizer}, $toc->{sflap}->{port}, $toc->{sflap}->{nickname}, $roasted_password, $language, $version); } sub sflap_data { my ($self, $data, $toc) = @_; my ($cmd, $args); ($cmd, $args) = ($data =~ /^(\w+)\:(.*)$/); return unless defined $cmd && defined $args; if ($cmd eq "SIGN_ON") { ($toc_version) = ($args =~ /^TOC(.*)$/); $toc->callback("SIGN_ON", $toc_version); } if ($cmd eq "CONFIG") { $toc->callback("CONFIG", $args); } if ($cmd eq "NICK") { ($beautified_nick) = ($args =~ /^(.*)$/); $toc->callback("NICK", $beautified_nick); } if ($cmd eq "IM_IN") { ($nickname, $autoresponse, $message) = ($args =~ /^(.*)\:(.*)\:(.*)$/); $toc->callback("IM_IN", $nickname, $autoresponse, $message); } if ($cmd eq "UPDATE_BUDDY") { ($nickname, $online, $evil, $signon_time, $idle_time, $class) = ($args =~ /^(.*)\:(.*)\:(.*)\:(.*)\:(.*)\:(.*)$/); $toc->callback("UPDATE_BUDDY", $nickname, $online, $evil, $signon_time, $idle_Time, $class); } if ($cmd eq "ERROR") { ($code, $args) = ($args =~ /^(\d*).?(.*)$/); $toc->callback("ERROR", $code, $args); } if ($cmd eq "EVILED") { ($evil_level, $nickname) = ($args =~ /^(.*)\:(.*)$/); $toc->callback("EVILED", $evil_level, $nickname); } if ($cmd eq "CHAT_JOIN") { ($room_id, $room_name) = ($args =~ /^(.*)\:(.*)$/); $toc->callback("CHAT_JOIN", $room_id, $room_name); } if ($cmd eq "CHAT_IN") { ($room_id, $nickname, $whisper, $message) = ($args =~ /^(.*)\:(.*)\:(.*)\:(.*)$/); $toc->callback("CHAT_IN", $room_id, $nickname, $whisper, $message); } if ($cmd eq "CHAT_UPDATE_BUDDY") { ($room_id, $inside, $nicknames) = ($args =~ /^(.*)\:(.*)\:(.*)$/); $toc->callback("CHAT_UPDATE_BUDDY", $room_id, $inside, $nicknames); } if ($cmd eq "CHAT_INVITE") { ($room_name, $room_id, $nickname, $message) = ($args =~ /^(.*)\:(.*)\:(.*)\:(.*)$/); $toc->callback("CHAT_INVITE", $room_name, $room_id, $nickname, $message); } if ($cmd eq "CHAT_LEFT") { ($room_id) = ($args =~ /^(.*)$/); $toc->callback("CHAT_LEFT", $room_id); } if ($cmd eq "GOTO_URL") { ($window_name, $url) = ($args =~ /^(.*)\:(.*)$/); $toc->callback("GOTO_URL", $window_name, $url); } if ($cmd eq "PAUSE") { $toc->callback("PAUSE"); } } sub sflap_error { my ($self, $data, $toc) = @_; return; } sub sflap_signoff { my ($self, $data, $toc) = @_; $toc->callback("CLOSED"); #foreach $k (keys %{$toc->{callback}}) { # print "Deleting .. $k\n"; # delete $toc->{callback}{$k}; #} $toc->destroy(); return; } sub test { my ($self) = @_; return \&test($self); } sub send_signoff { my ($self) = @_; $self->{sflap}->send($AOL::SFLAP::SFLAP_SIGNOFF, ""); } 1; __END__