AOL-TOC
view release on metacpan or search on metacpan
use Socket;
$VERSION = "0.33";
$SFLAP_SIGNON = 1;
$SFLAP_DATA = 2;
$SFLAP_ERROR = 3;
$SFLAP_SIGNOFF = 4;
$SFLAP_KEEPALIVE = 5;
sub register_callback {
my ($self, $chan, $func, @args) = @_;
#print "register_callback() func $func for chan $chan adding to $self->{callback}{$chan}\n";
#print " self $self selfcb = $self->{callback}\n";
push (@{$self->{callback}{$chan}}, $func);
@{$self->{callback}{$func}} = @args;
return;
}
sub clear_callbacks {
my ($self) = @_;
my $k;
print "...............C SFLAP clear_callbacks\n";
for $k (keys %{$self->{callback}}) {
print ".............C Clear key ($k)\n";
delete $self->{callback}{$k};
}
print "...............S SFLAP scan callbacks\n";
for $k (keys %{$self->{callback}}) {
print ".............S Scan key ($k)\n";
}
}
sub callback {
my ($self, $chan, @args) = @_;
my $func;
for $func (@{$self->{callback}{$chan}}) {
#print ("callback() calling a func $func for $chan fd $self->{fd}..\n");
eval { &{$func} ($self, @args, @{$self->{callback}{$func}}) };
}
return;
}
sub new {
my ($tochost, $authorizer, $port, $nickname) = @_;
my $self;
my $ipaddr;
if ($port =~ /\D/) { $port = getservbyname($port, 'tcp') }
die "invalid port" unless $port;
$ipaddr = inet_aton($tochost);
die "unknown host" unless $ipaddr;
ipaddr => $ipaddr,
port => $port,
nickname => $nickname,
sequence => 1
};
bless($self);
return $self;
}
sub destroy {
my ($self) = @_;
print "sflap destroy\n";
CORE::close($self->{fd});
$self = undef;
return;
}
sub close {
my ($self) = @_;
my $k;
print "sflap close\n";
$self->clear_callbacks();
#CORE::close($self->{fd});
return;
}
sub set_debug {
my ($self, $level) = @_;
$self->{debug_level} = $level;
print "slfap debug level $level\n";
}
sub debug {
my ($self, @args) = @_;
if (exists $self->{debug_level} && $self->{debug_level} > 0) {
print @args;
}
}
sub __connect {
my ($self) = @_;
my $socksaddr = inet_aton("206.223.45.1");
my $proto = getprotobyname('tcp');
my $sin = sockaddr_in(1080, $socksaddr);
my $fd = IO::Handle->new();
socket($fd, PF_INET, SOCK_STREAM, $proto) || die "socket: $!";
connect($fd, $sin) || die "connect: $!";
$buffer = pack("ccncccca*c", 4, 1, 443, 198, 81, 3, 52, "jamersepoo", 0);
syswrite($fd, $buffer, 19);
return ($fd);
}
sub _connect {
my ($self) = @_;
my $proto = getprotobyname('tcp');
my $sin = sockaddr_in($self->{port}, $self->{ipaddr});
my $fd = IO::Handle->new();
socket($fd, PF_INET, SOCK_STREAM, $proto) || die "socket: $!";
connect($fd, $sin) || die "connect: $!";
return ($fd);
}
sub connect {
my ($self) = @_;
my $fd;
if ($self->{proxy}) {
$fd = &{$self->{proxy}};
} else {
$fd = $self->_connect;
}
$self->{fd} = $fd;
$foo = $self->write("FLAPON\r\n\r\n", 10);
$self->recv();
return $fd;
}
sub recv {
my ($self) = @_;
my ($buffer, $from, $xfrom) = '';
my ($fd) = $self->{fd};
$foo = CORE::sysread($fd, $buffer, 6);
if ($foo <= 0) {
#print "recv failed! calling signoff....\n";
$self->callback($SFLAP_SIGNOFF);
return;
}
$self->debug("sflap recv ($self->{fd}) $foo chan = $chan seq = $seq len = $len\n");
$foo = CORE::sysread($fd, $data, $len);
$self->debug(" data = $data\n");
$self->callback($chan, $data);
return $buffer;
}
sub send {
my ($self, $chan, $data, $length) = @_;
my $buffer;
my $format;
if (!$length) {
$length = length($data);
}
if ($chan == $SFLAP_DATA) {
$format = "cCnna*C";
$self->{sequence} ++;
$buffer = pack($format, 42, $chan, $self->{sequence},
$length, $data, 0);
($id, $ch, $seq, $len, $data, $nuller) = unpack($format, $buffer);
$foo = CORE::syswrite($self->{fd}, $buffer, $length + 6);
$self->debug("sflap send ($self->{fd}) $foo chan = $ch seq = $seq len = $len data = $data\n");
}
sub write {
my ($self, $buffer, $len, $noflap) = @_;
my $fd = $self->{fd};
return CORE::syswrite($fd, $buffer, $len);
}
sub flush {
my $self = shift;
}
1;
xjharding@newbedford.k12.ma.us cleaned it up and added DOC
james@foo.org was the original author
=head1 SEE ALSO
Net::AIM, a new module, but it doesn't have the features of this one
=cut
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 "\[") ||
$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);
#$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);
($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__
tocbot/do.pl view on Meta::CPAN
#
# do.pl
#
sub do_init {
tocbot_register_command("do", \&do_func);
}
sub do_func {
my ($nickname, $cmd, @args) = @_;
if ($cmd eq "send_im") {
($nickname, @message) = @args;
print "tocbot: do: send_im($nickname, @message)\n";
$toc->send_im($nickname, "@message");
}
if ($cmd eq "add_buddy") {
print "tocbot: do: add_buddy(@args)\n";
tocbot/fortune.pl view on Meta::CPAN
#
# fortune.pl
#
sub fortune_init {
tocbot_register_command("fortune", \&fortune_func);
}
sub fortune_func {
my ($nickname, $relayto, @message) = @_;
my @fortune;
print "tocbot: fortune: $nickname requested a fortune!\n";
open (ff, "/bin/fortune|");
@fortune = <ff>;
close (ff);
$toc->send_im($nickname, "Your fortune is:");
tocbot/ident.pl view on Meta::CPAN
#
# ident.pl
#
sub ident_init {
tocbot_register_command("ident", \&ident_identify);
tocbot_register_command("unident", \&ident_unidentify);
}
sub ident_identify {
my ($nickname, @args) = @_;
print "tocbot: ident: identified user $nickname\n";
$toc->add_buddy($nickname);
}
sub ident_unidentify {
my ($nickname, @args) = @_;
print "tocbot: ident: unidentified user $nickname\n";
$toc->remove_buddy($nickname);
}
1;
tocbot/relay.pl view on Meta::CPAN
#
# relay.pl
#
sub relay_init {
tocbot_register_command("relay", \&relay_func);
}
sub relay_func {
my ($nickname, $relayto, @message) = @_;
print "tocbot: relay: relay message \"@message\" to $relayto\n";
$toc->send_im($relayto, "Message relayed from $nickname: @message");
}
1;
tocbot/tocbot.pl view on Meta::CPAN
$toc->register_callback("CLOSED", \&client_closed);
$toc->register_callback("SIGN_ON", \&client_signon);
$toc->register_callback("IM_IN", \&client_im);
$toc->register_callback("UPDATE_BUDDY", \&client_buddy);
while (1) {
$toc->dispatch();
}
sub client_im {
my ($self, $nickname, $autoresponse, $message) = @_;
my $cmd, $args;
print "tocbot: $nickname says \"$message\"\n";
if ($autoresponse eq "T") {
print "tocbot: $nickname is away, ignoring.\n";
return;
}
tocbot/tocbot.pl view on Meta::CPAN
if ($message =~ /HELP/i) {
send_help($nickname);
return;
}
$toc->send_im($nickname, "Hi, I'm a bot. Do you need 'HELP'?");
}
sub send_help {
my ($nickname) = @_;
$toc->send_im($nickname, "I'm a bot. I have the following modules installed:");
sleep(1);
$toc->send_im($nickname, " @tocbot_modules");
sleep(1);
$toc->send_im($nickname, "You can invoke a module by telling me 'bot(module ...)'");
}
sub do_command {
my ($nickname, $cmd, $args) = @_;
my @eargs = split(' ', $args);
tocbot_exec_command($cmd, $nickname, @eargs);
return 1;
}
sub client_signon {
$toc->add_buddy("jamersepoo", "jamers20VA");
$toc->send_im("jamersepoo", "tocbot online");
}
sub client_error {
my ($self, $code) = @_;
print "tocbot: TOC error $code.\n";
}
sub client_closed {
my ($self) = @_;
print "tocbot: connection closed, exiting.\n";
exit (0);
}
sub client_buddy {
my ($self, $nickname, $online, $evil, $signon_time, $idle_time, $class) = @_;
print "tocbot: buddy $nickname signed on\n";
}
sub tocbot_register_command {
my ($cmd, $func, @args) = @_;
print "Registered command '$cmd'\n";
$tocbot_commands{$cmd} = $func;
}
sub tocbot_exec_command {
my ($cmd, @args) = @_;
eval { &{$tocbot_commands{$cmd}} (@args) };
}
( run in 0.288 second using v1.01-cache-2.11-cpan-4d50c553e7e )