#!/usr/bin/perl -w use lib "./blib/lib"; use strict; use warnings; use Getopt::Long; use Net::OSCAR qw(:standard :loglevels); use Net::OSCAR::Utility qw(randchars); use IO::Poll; eval { require Data::Dumper; }; use vars qw($oscar %fdmap $poll); #$Carp::Verbose = 1; $| = 1; sub connection_changed($$$) { my($oscar, $connection, $status) = @_; my $h = $connection->get_filehandle(); $connection->log_printf(OSCAR_DBG_DEBUG, "State changed (FD %d) to %s", fileno($h), $status); my $mask = 0; if($status eq "deleted") { delete $fdmap{fileno($h)}; } else { $fdmap{fileno($h)} = $connection; if($status eq "read") { $mask = POLLIN; } elsif($status eq "write") { $mask = POLLOUT; } elsif($status eq "readwrite") { $mask = POLLIN | POLLOUT; } } $poll->mask($h => $mask); } $poll = IO::Poll->new(); $poll->mask(STDIN => POLLIN); $oscar = Net::OSCAR->new(); $oscar->set_callback_connection_changed(\&connection_changed); $oscar->loglevel(10); $oscar->server(local_port => 5190); my($inline, $inchar); while(1) { next unless $poll->poll(); my $got_stdin = 0; my @handles = $poll->handles(POLLIN | POLLOUT | POLLHUP | POLLERR | POLLNVAL); foreach my $handle (@handles) { if(fileno($handle) == fileno(STDIN)) { $got_stdin = 1; } else { my($read, $write, $error) = (0, 0, 0); my $events = $poll->events($handle); $read = 1 if $events & POLLIN; $write = 1 if $events & POLLOUT; $error = 1 if $events & (POLLNVAL | POLLERR | POLLHUP); my $conn = $fdmap{fileno($handle)}; #$conn->log_print(OSCAR_DBG_DEBUG, "Got r=$read, w=$write, e=$error"); $conn->process_one($read, $write, $error); next unless $write; my $hash = $Net::OSCAR::ServerCallbacks::SESSIONS; } } next unless $got_stdin; sysread(STDIN, $inchar, 1); if($inchar eq "\n") { my($cmd, @params) = split(/[ \t]+/, $inline); $inchar = ""; $inline = ""; $cmd ||= ""; if($cmd eq "eval") { eval(join(" ", @params)); if($@) { print "$@\n"; } } elsif($cmd eq "migrate") { my $session = $params[0]; if(!$session) { print "Usage: migrate screenname\n"; } else { my $bos = $Net::OSCAR::ServerCallbacks::SESSIONS->{$params[0]}->{sessions}->[0]; my $families = $bos->{families}; my $cookie = randchars(8); $Net::OSCAR::ServerCallbacks::COOKIES{$cookie} = {sn => $params[0]}; $bos->proto_send(protobit => "migrate", protodata => { families => $families, peer => "127.0.0.1:5190", cookie => $cookie }); } } } else { $inline .= $inchar; } }