#!/usr/bin/perl
# -*- Mode: cperl -*-
# Copyright (C) 2000, 2001, 2002 by MandrakeSoft, Pixel <pixel@mandrakesoft.com>
# and others MandrakeSoft folks.
# Redistribution of this file is permitted under the terms of the GNU
# Public License (GPL)
##
# Description: Detect what type of loader you have on your MBR
# If neither LILO nor GRUB is found on MBR, try partitions too.
# $Id: detectloader,v 1.20 2002/11/07 11:59:32 sbenedict Exp $

use MDK::Common;

my ($quiet);

if ($ARGV[0] =~ /^-q/) {
    $quiet=1;
    shift;
}

my $loader = $ENV{DEFAULT_LOADER} || detect();
print uc($loader), "\n";


sub detect {
    my @all = read_partitions();
    my @parts = grep { $_->{dev} =~ /\d$/ } @all;
    my @disks = grep { $_->{dev} !~ /\d$/ } @all;

    return "aboot" if arch() =~ /alpha/;

    my $loader;
    foreach (@disks) {
	$loader = typeOfMBR($_) and return $loader;
    }
    warn "no bootloader on MBR, trying partitions!\n" if !$quiet;
    foreach (@parts) {
	$loader = typeOfMBR($_) and return $loader;
    }
}

BEGIN {

@known_boot_loaders = qw(lilo grub yaboot);

# keep this in sync with DrakX
@MBR_signatures = (
    [ 'empty', 0, "\0\0\0\0" ],
    [ 'grub', 0x6,  "GRUB" ],
    [ 'grub', 0, "\xEBG", 0x17d, "stage1 \0" ],
    [ 'grub', 0, "\xEBH", 0x17e, "stage1 \0" ],
    [ 'grub', 0, "\xEBH", 0x18a, "stage1 \0" ],
    [ 'grub', 0, "\xEBH", 0x181, "GRUB \0" ],
    [ 'lilo', 0x2,  "LILO" ],
    [ 'lilo', 0x6,  "LILO" ],
if_(arch() =~ /ppc/,
    [ 'yaboot', 0xA0,  "PowerPC" ],
    map { [ 'yaboot', 0, "PM", 0x200 * $_ + 0x30, "Apple_Bootstrap\0" ] } 0 .. 61
),
);

}

sub typeOfMBR {
    my ($disk) = @_;


    my $dev = "/dev/$disk->{dev}";
    my $tmp;
    if (! -e $dev) {
	$tmp = "/tmp/.detect_loader.tmpdev";
	-e $tmp and die "detectloader: block special file $tmp already exist\n";
	system("mknod", $tmp, "b", $disk->{major}, $disk->{minor});
	$? == 0 or die "detectloader: can't create block special file $tmp\n";
	-l $tmp and die "detectloader: something weird is happening";
    }
    my $t = typeFromMagic($tmp || $dev, @MBR_signatures);
    unlink $tmp if $tmp;

    member($t, @known_boot_loaders) or return;

    $t;
}

sub read_partitions {
    my (undef, undef, @all) = cat_("/proc/partitions");
    grep {
	$_->{size} != 0x3fffffff # skip cdroms (otherwise stops cd-audios)
    } map {
	my %l;
	@l{qw(major minor size dev)} = split;
	\%l;
    } @all;
}
