#!/usr/bin/perl
# -*- Mode: cperl -*-
# Copyright (C) 2000, 2001 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.12 2001/08/04 19:58:21 prigaux Exp $

use MDK::Common;

%skiplist;

my ($quiet);

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

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

sub read_skiplist(){
    open SL, "/etc/bootloader/skiplist" or return;
    my @skip = <SL>;
    foreach (@skip) {
    chomp;
    $skiplist{$_}=1;
    }
}

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

    read_skiplist();
    my $loader;
    foreach (@disks) {
    if (not($skiplist{$_->{dev}})){
	$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);

# 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" ],
);

}

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 {
	if (open F,"/proc/ide/$_->{dev}/media"){
	     $m=<F>; chomp($m);
	}else{
	    $m="unknown";
	}
	(not ($m eq "cdrom")) and $_->{size} != 0x3fffffff # skip cdroms (otherwise stops cd-audios)
    } map { 
	my %l; 
	@l{qw(major minor size dev)} = split; 
	\%l;
    } @all;
}
