#!/usr/bin/perl
##
# $Id: foot-wrapping,v 1.34 2004/07/29 07:05:47 mud Exp $
#
# 2000, unicorn
#

$goddies='saboteur@saboteur.com.ua;fd@localhost';
$myaddress='saboteur@saboteur.com.ua';

unlink "install.txt", "shutdown.txt";

use IO::Handle;
use POSIX qw(strftime);

pipe FROMGDB, GOUT;
pipe GIN, TOGDB;

GOUT->autoflush();
TOGDB->autoflush();

open PIDF, ">/tmp/rom.pid";
print PIDF "$$";
close PIDF;

if(!fork) {
	close FROMGDB, TOGDB, STDIN, STDOUT;

	open STDIN, "<&GIN" or die "Can't `dup' $!\n";
	open STDOUT, ">&GOUT" or die "Can't `dup' $!\n";

	exec "/usr/bin/gdb", "rom" or die "Can't `exec' $!\n";
	exit;
}

close GOUT, GIN;


sub restart {
	print "restarting\n";
	open SL, ">>start.log";

	$now=localtime;

	if (-f 'shutdown.txt') {
		unlink 'shutdown.txt';
		print SL " *** Shutdown *** \n$now\n";
                exit;
	}

	print SL "****************************** Started\n$now\n";
	close SL;

	sleep 2;
	print TOGDB "run\n";
}

sub readresponse {
	my $tmp, $r;

	$tmp=$/;
	$/="(gdb) ";
	($r=<FROMGDB>) =~ s/\(gdb\) $//;
	$/=$tmp;

	return $r;
}

sub gdbcmd {
	my ($cmd)=@_;

	print TOGDB "$cmd\n";
	return readresponse;
}

sub attach {
	print "Hello from GDB $_\n";
	readresponse;

	gdbcmd "handle SIGPIPE nostop noprint pass";
	gdbcmd "b gdb_ipc";

	restart;
}

sub ipc {
	$rc = eval gdbcmd 'printf "%s", arg';
	gdbcmd "call strcpy(rc, \"$rc\")";
}

sub brk {
	$brk_str = $_;
	$tmp = readresponse;
	$_ = $brk_str;
	
	ipc if /ipc/;

	print TOGDB "c\n";
}

sub crash {
	$signame = $_;
	$crashinfo = readresponse;
	
	$traceinfo = gdbcmd "bt full";
	
	$miscinfo = "";

	open GDBSCRIPT, "oncrash";
	while(<GDBSCRIPT>) {
		chop;
		next if /^[ \t]*$/ or /^#/;


		$miscinfo .= s/% *// ? 
			"$_\n" : 
			"gdb> $_\n\n" . gdbcmd ($_) . "\n";
	}
	close GDBSCRIPT;

	open SM, "| sendmail $goddies";
	print SM <<EOF
From: (smelly) GDB Foot Wrapping <$myaddress>
To: MUD Gods <$goddies>
Subject: FD CRASH via $signame

                  -========= [Crash details] ==========-
$crashinfo

                  -=========== [Backtrace] ============-
$traceinfo

                  -============== [misc] ==============-
$miscinfo

-- 
Sincerely yours,
   The GNU Debugger (;
EOF
;
	close SM;

	print TOGDB "c\n";
}

while(<FROMGDB>) {
	chop;
	s/^\(gdb\) //;
	print "<gdb> $_\n";

	attach if /Ubuntu 7.11.1-0ubuntu1~16.5/;
	crash if s/^Program received signal .*, (.*)$/\1/;
	restart if /^The program no longer exists/;
	restart if /^Program exited/;
	brk if /^Breakpoint/;
}

