#!/usr/bin/perl

$myname = $0;
undef($newkernel);  #if we ever want to boot an image other than autokern.image
undef($initrd);     #for distro testing, etc.
$kernellabel = $ARGV[0];
quotemeta($kernellabel);

# build a single string of all of the command line arguments
foreach $argument (1 .. $#ARGV)
	{
	$newargs = join(" ",$newargs, $ARGV[$argument]);
	}

die "$0 needs to be passed a kernel label to boot\n" unless($kernellabel);

if ($kernellabel eq "_default_")
	{
	&reboot;
	}


#$myname = "yaboot";

if ($myname =~ m/lilo/i)
	{
	&setlilo;
	}
elsif ($myname =~ m/grub/i)
	{
	&setgrub;
	}
elsif ($myname =~ m/yaboot/i)
	{
	&setyaboot;
	}
else
	{ # Look at the clues for which bootloader is in use

	# lilo puts the string BOOT_IMAGE in /proc/cmdline
	open(PROCCMDLINE, "/proc/cmdline");
	$thecommandline = <PROCCMDLINE>;
	close(PROCCMDLINE);

	# ppc or intel?  ppc uses only yaboot
	open (BINUNAME, "/bin/uname -m |");
	$uname = <BINUNAME>;
	close (BINUNAME);

	# lilo in the boot sector on intel will say LILO
	if (open(DISK, "/dev/hda"))
		{
		read DISK, $buffer, 16;
		close(DISK);
		}
	elsif (open(DISK, "/dev/sda"))
		{
		read DISK, $buffer, 16;
		close(DISK);
		}
	if ((-e "/etc/lilo.conf") && ($buffer =~ m/LILO/i) && ($thecommandline =~ m/BOOT_IMAGE/))
		{ # must be lilo on intel    Will not match non-bootsector lilo
		&setlilo;	
		}
	elsif ((-e "/etc/yaboot.conf") && ($uname =~ m/ppc/i))
		{ # must be yaboot on ppc    no other options for ppc
		&setyaboot;
		}
	elsif (-e "/boot/grub/menu.lst")
		{ # default to grub
		&setgrub;
		}
	else
		{
		die "$myname there is no config file for a bootloader!\n";
		}
	}

$masterboot = $bootconfigfile . ".BACKUP";
system("cp $bootconfigfile $masterboot") unless (-e $masterboot);

$saveme = $/;
undef $/;
open(CONFIGFILE, "$masterboot") || die "cant open $masterboot\n";
$wholefile = <CONFIGFILE>;
close(CONFIGFILE);
$/ = $saveme;

$copyofwholefile = $wholefile;
#while ($copyofwholefile =~ m/(^$separator.*?(?=^$separator))(.*)/gims)
while (($copyofwholefile =~ m/(^$separator.*?(?=^$separator))(.*)/gims) || ($copyofwholefile =~ m/(^$separator.*(?!^$separator))(.*)/gims))

	{
	$thematch = $1;
	$therest = $2;
	push(@stanzas, $thematch);
	$copyofwholefile = $therest;
	}
push(@stanzas, $therest);  #Push the last stanza on too

$foundit = 0;
$grubindex =0;
foreach $stanza (@stanzas)
	{
	if ($stanza =~ m/(^\s*$labeltag.*?\s*$kernellabel$)/gims)
		{
		$foundit++;
		$matchingstanza = $stanza;

		if (($matchingstanza=~ m/^\s*$kerneltag\s*(.*?)\s+(.*?)$/gims) && ($newkernel))
			{
			# BTW, This is kernel LABEL, not a vmlinux image
			$oldkernel = $1;
			$oldextraargs = $2;
			$temp = quotemeta($oldkernel);
			$matchingstanza =~ s/$temp/$newkernel/gi;
			}

		if (($matchingstanza=~ m/^\s*root\s*\=\s*(.*?)\s+/gims) && ($newroot))
			{
			$oldroot= $1;
			$temp = quotemeta($oldroot);
			$matchingstanza =~ s/$temp/$newroot/gi;
			}

		if ($initrd)
			{
			if ($matchingstanza=~ m/^\s*\Qinitrd\E(.*?)$/gims)
                        	{
                        	$oldinitrd = $1;
                        	$matchingstanza =~ s/$oldinitrd/ $initrd/gi if $grub;
                        	$matchingstanza =~ s/$oldinitrd/ \= $initrd/gi if $lilo;
				}
			else
				{
				$matchingstanza = $matchingstanza . "initrd $initrd\n" if $grub;
				$matchingstanza = $matchingstanza . "initrd = $initrd\n" if $lilo;
				}
			}
		if ((($matchingstanza =~ m/^\s*$argstag\s*(.*?)\s+(.*?)$/gims) && ($newargs) && ($grub)))
			{
			$oldkernel = $1;
			$oldextraargs = $2;
			$newargs = $oldextraargs . " " . $newargs;
			$temp = quotemeta($oldextraargs);
			$matchingstanza =~ s/$temp/$newargs/gi;
			}

		#print "argstag is -->$argstag<--\n";
		#print "yaboot is -->$yaboot<--\n" if ($yaboot || $lilo);
		#print "lilo is -->$lilo<--\n" if ($yaboot || $lilo);
		#print "newargs passed in -->$newargs<--\n" if $newargs;
		#print "matchingstanza is -->$matchingstanza<--\n";
		quotemeta($argstag);
		#if ((($matchingstanza=~ m/^\s*$argstag\s*\=\s*\Q"\E(.*)\Q"\E/gims) && ($newargs) && ($yaboot || $lilo)))
		$teststanza = $matchingstanza;
		chop($teststanza);
		if ((($teststanza=~ m/^\s*($argstag\s*\=\s*\Q"\E.*)\Q"\E/gims) && ($newargs) && ($yaboot || $lilo)))
			{
			$oldextraargs = $1;
			#print "oldextraargs -->$oldextraargs<--\n";
			$newargs = $oldextraargs . " " . $newargs;
			#print "newargs -->$newargs<--\n";
			$temp = quotemeta($oldextraargs);
			$matchingstanza =~ s/$temp/$newargs/gi;
			}
		#print "===========\n";
		#print $stanza;
		#print "===========\n";
		$temp = quotemeta($stanza);
		$wholefile =~ s/$temp/$matchingstanza/gi;
		$wholefile =~ s/\Qdefault\E\s+\d+/default $grubindex/gi if $grub;
		$wholefile =~ s/^\Qdefault\E\s+=.*?$/default = $kernellabel/gims if $lilo;
		$wholefile =~ s/^\Qdefault\E\s+=.*?$/default = $kernellabel/gims if $yaboot;
		}
	else
		{
		#print "------\n";
		#print $stanza;
		#print "------\n";
		}
	$grubindex++;
	}

if ($foundit > 1)
	{
	print "Oops, $myname found $foundit entries named $kernellabel in $bootconfigfile!\n";
        exit 86;
	}
elsif ($foundit)
	{
	#print "$myname: Set up to boot the following entry in $bootconfigfile:\n";
	#print $matchingstanza;
	system ("cp $bootconfigfile $bootconfigfile.autobench.bak");     # doing this for compatability even though I never use it
	open (OUTFILE, ">$bootconfigfile") || die "$myname couldn't write to $bootconfigfile\n";
        print OUTFILE "########## WARNING, THIS FILE WILL BE OVERWRITTEN BY AUTOBENCH.##########\n";
        print OUTFILE "########## EDIT $masterboot INSTEAD  ##########\n\n";
	print OUTFILE $wholefile;
	close (OUTFILE);
	system("/sbin/lilo") if $lilo;  #setve also did lilo -R commandlineargs

	&reboot;
        }
else
	{
	print "Oops, $myname found no entries named $kernellabel in $bootconfigfile!\n";
        exit 86;
	}


sub reboot
	{
	# reboot the autobench way
        if ( -e "$AUTODIR/var/run/managed" )
		{
		$AUTODIR = $ENV{'AUTODIR'};
		open (OUTFILE, ">$AUTODIR/var/run/status-pipe");
		print OUTFILE "quit_event: machine_reboot\n";
		close (OUTFILE);
		system("daemonize shutdown -r +1");
        	}
        else 
		{
           	system("reboot");
        	}
	exit 87;
	}

sub setlilo
	{
	$lilo=1;
	$separator = "image";
	$kerneltag = "image =";
	$labeltag = "label";
	$argstag = "append";
	$bootconfigfile= "/etc/lilo.conf";
	}
sub setgrub
	{
	$grub=1;
	$separator = "title";
	$kerneltag = "kernel";
	$labeltag = "title";
	$argstag = $kerneltag;
	$bootconfigfile= "/boot/grub/menu.lst";
	#$bootconfigfile= "/home/tcw/baseball.grub.conf";
	}
sub setyaboot
	{
	$yaboot=1;
	$separator = "image";
	$kerneltag = "image =";
	$labeltag = "label";
	$argstag = "append";
	$bootconfigfile= "/etc/yaboot.conf";
	# for SuSE... will it break the others?
	#if [ ! -e /etc/lilo.conf ]; then
	#log "creating symlink of lilo.conf to yaboot.conf"
	#ln -s /etc/yaboot.conf /etc/lilo.conf
	}
