File: gdbbot.pl

package info (click to toggle)
uml-utilities 20070815.4-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, sid, trixie
  • size: 728 kB
  • sloc: ansic: 3,391; perl: 1,277; makefile: 239; exp: 129; sh: 122
file content (107 lines) | stat: -rw-r--r-- 2,395 bytes parent folder | download | duplicates (9)
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;