1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
|
use IO::Pty;
use IPC::Open2;
use Net::IRC;
use POSIX;
use Fcntl;
use strict;
my $irc = new Net::IRC;
my $pty = new IO::Pty;
my $pid;
my $key;
my %trust = ();
my $conn = $irc->newconn(Server => 'irc.openprojects.net',
Port => 6667,
Nick => 'gdbbot',
Ircname => 'Vlad the Debugger',
Username => 'gdb')
or die "gdbbot: Can't connect to IRC server.\n";
sub start_gdb {
my $cmd = shift;
$pid = fork();
!defined($pid) and die "Couldn't fork : $!";
if($pid == 0){
POSIX::setsid() || warn "Couldn't perform setsid $!\n";
my $tty = $pty->slave();
my $name = $tty->ttyname();
# close($pty);
close STDIN; close STDOUT; close STDERR;
open(STDIN,"<&". $tty->fileno()) ||
die "Couldn't reopen ". $name ." for reading, $!";
open(STDOUT,">&". $tty->fileno()) ||
die "Couldn't reopen ". $name ." for writing, $!";
open(STDERR,">&". fileno(STDOUT)) ||
die "Couldn't redirect STDERR, $!";
exec ($cmd);
die "Couldn't exec : $!";
}
else {
fcntl($pty, Fcntl::F_SETFL, Fcntl::O_NONBLOCK);
print "gdb pid is $pid\n";
return $pty;
}
}
sub on_connect {
my $self = shift;
print "Joining \#umldebug...\n";
$self->join("#umldebug");
$key = rand(1<<31);
print "Your secret is $key\n";
my $cmd = "gdb linux";
my $pty = start_gdb($cmd);
$irc->addfh($pty->fileno(), \&gdb_output, "rw");
}
sub on_public {
my ($self, $event) = @_;
my @to = $event->to;
my ($nick, $mynick) = ($event->nick, $self->nick);
my ($arg) = ($event->args);
$arg !~ /^gdbbot/ and return;
$arg =~ s/^gdbbot:\s*//;
if($arg =~ /\^C/){
kill 2, $pid;
}
elsif(defined($key) && ($arg eq $key)){
$self->me("#umldebug", "trusts $nick");
$trust{$nick} = 1;
$key = undef;
}
elsif($trust{$nick} == 1){
if($arg =~ /trust (.*)/){
$trust{$1} = 1;
$self->me("#umldebug", "trusts $1");
}
else {
print $pty "$arg\n";
}
}
else {
$self->me("#umldebug", "doesn't trust $nick");
}
}
sub gdb_output {
while(<$pty>){
$conn->privmsg("#umldebug", "$_");
}
}
sub on_msg {
my ($self, $event) = @_;
my $nick = $event->nick;
$self->privmsg($nick, "Sorry, I don't understand messages yet.");
}
$conn->add_global_handler(376, \&on_connect);
$conn->add_handler('msg', \&on_msg);
$conn->add_handler('public', \&on_public);
$irc->start;
|