#!/usr/bin/perl -w use IO::Socket::INET; use IPC::Open2; use Net::AIM; my $aim = new Net::AIM; my $conn = $aim->newconn(Screenname => 'botname', Password => 'botpass'); my %users = (); my %connmap = (); sub on_error { my $self = shift; my $event = shift; print "=== ERROR ===\n"; $event->dump(); } sub on_im { my $self = shift; my $event = shift; $event->dump(); my ($from, $flag, $msg) = @{$event->{'args'}}; $from = lc($from); # strip HTML (and maybe a little more) $msg =~ s/\<[^>]+\>//g; my $ic = $users{$from}; if ($msg =~ s:^/(\w+)\s*::) { # command from user my $cmd = lc($1); print "$from: command $cmd\n"; if ($cmd eq "telnet") { if (defined $ic) { $ic->close(); delete $users{$from}; delete $connmap{$ic}; } my ($server, $port) = split(/\s+/, $msg, 2); $ic = IO::Socket::INET->new('PeerHost' => "$server", 'PeerPort' => $port, 'Proto' => 'tcp', 'Type' => SOCK_STREAM); if (defined $ic) { $ic->blocking(0); $users{$from} = $ic; $connmap{$ic} = $from; $aim->addfh($ic, \&telnet_hook); print "Started irc: $ic\n"; $self->send_im($from, "Connected."); } else { $self->send_im($from, "Unable to connect"); } } elsif ($cmd eq "ping") { warn "ping from $from\n"; $self->send_im($from, "/pong $from " . localtime(time)); } elsif ($cmd eq "quit") { exit; } elsif ($cmd eq "calc") { if (defined $ic) { $ic->close(); delete $users{$from}; delete $connmap{$ic}; } } } else { if (defined $ic) { $msg .= "\n" unless $msg =~ /\n$/; $ic->print("$msg\n"); } else { $self->send_im($from, "whatup!"); } } } my $aconn = $aim->getconn(); my $aim_sock = $aconn->get_socket(); $aconn->set_handler('error', \&on_error); $aconn->set_handler('im_in', \&on_im); $aim->start(); # # hooks # sub telnet_hook { my ($fh) = @_; my $user = $connmap{$fh}; if ($fh->eof()) { $aim->remfh($fh); $fh->close(); delete $connmap{$fh}; delete $users{$user}; print "Closed from $user."; $aim->send_im($user, "Closed."); } else { my $out = ""; my $res = 0; my $info = ""; while (($res = $fh->read($info, 768)) > 0) { $out .= $info; } print "Read $res from $fh for $user: $info\n"; if (length($out) > 950) { $aim->send_im($user, "...$info"); } else { $aim->send_im($user, $out); } } }