package bootloader_utils; # $Id: bootloader_utils.pm,v 1.2 2003/12/04 12:29:17 at Exp $ #-------------------------------------------------------------------- # Copyright (C) 2000, 2001, 2002 by MandrakeSoft. # Chmouel Boudjnah . # # Redistribution of this file is permitted under the terms of the GNU # Public License (GPL) #-------------------------------------------------------------------- # Copyright (C) 2003 by ALT Linux Team, # Alexey Tourbin . #-------------------------------------------------------------------- require Exporter; @ISA = qw(Exporter); @EXPORT_OK = qw(mnt2dev partitions typeOfMBR getroot); use strict; sub fstab { open my $f, '/etc/fstab' or return; my @fstab; while (<$f>) { next if /^\s*#/; my @ent = split; push @fstab, \@ent; } return @fstab; } sub mnt2dev { my $mnt = shift; foreach my $ent (fstab()) { return $$ent[0] if $$ent[1] eq $mnt; } return; } my @MBR_signatures = ( [ 'empty', 0, "\0\0\0\0" ], [ '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" ], [ 'grub', 0x6, "GRUB" ], [ 'osbs', 0x2, "OSBS" ], #- http://www.prz.tu-berlin.de/~wolf/os-bs.html [ 'pqmagic', 0xef, "PQV" ], [ 'BootStar', 0x130, "BootStar:" ], [ 'DocsBoot', 0x148, 'DocsBoot' ], [ 'system_commander', 0x1ad, "SYSCMNDRSYS" ], [ 'Be Os', 0x24, 'Boot Manager' ], [ 'os2', 0, "\xFA\xB8\x30\x00", 0xfA, "OS/2" ], [ 'TimO', 0, 'IBM Thinkpad hibernation partition' ], [ 'dos', 0xa0, "\x25\x03\x4E\x02\xCD\x13" ], [ 'dos', 0xa0, "\x00\xB4\x08\xCD\x13\x72" ], #- nt2k's [ 'dos', 0x60, "\xBB\x00\x7C\xB8\x01\x02\x57\xCD\x13\x5F\x73\x0C\x33\xC0\xCD\x13" ], #- nt's [ 'dos', 0x70, "\x0C\x33\xC0\xCD\x13\x4F\x75\xED\xBE\xA3" ], [ 'freebsd', 0xC0, "\x00\x30\xE4\xCD\x16\xCD\x19\xBB\x07\x00\xB4" ], [ 'freebsd', 0x160, "\x6A\x10\x89\xE6\x48\x80\xCC\x40\xCD\x13" ], [ 'dummy', 0xAC, "\x0E\xB3\x07\x56\xCD\x10\x5E\xEB" ], #- caldera? [ 'ranish', 0x100, "\x6A\x10\xB4\x42\x8B\xF4\xCD\x13\x8B\xE5\x73" ], [ 'os2', 0x1c2, "\x0A" ], [ 'Acronis', 0, "\xE8\x12\x01" ], ); sub typeFromMagic { my $fname = shift; sysopen my $fh, $fname, 0 or return; set: foreach my $set (@_) { my ($type, %magic) = @$set; while (my ($offset, $signature) = each %magic) { sysseek($fh, $offset, 0) or next set; my $n = length $signature; sysread($fh, my $buf, $n) == $n or next set; $buf eq $signature or next set; } return $type; } return; } use File::Temp qw(tempdir); use sigtrap qw(die normal-signals); sub typeOfMBR($) { my $disk = shift; my $dev = "/dev/$$disk{dev}"; unless (-b $dev) { my $dir = tempdir("bootloader.XXXXXXXXXX", CLEANUP => 1, TMPDIR => 1); $dev = "$dir/$$disk{dev}"; system "mknod", $dev, "b", $$disk{major}, $$disk{minor}; die "$0: cannot create block special file $dev\n" unless $? == 0 && -b $dev; } return typeFromMagic($dev, @MBR_signatures); } sub media_type { my $dev = shift; open my $fh, "/proc/ide/$dev/media" or return; my $type = <$fh>; chomp $type; return $type; } sub partitions { open my $fh, "/proc/partitions" or return; my @all; while (<$fh>) { next unless /\d/; my %ent; @ent{qw(major minor size dev)} = split; $ent{media} = media_type $ent{dev}; push @all, \%ent; } return @all; } sub getroot { if (open my $fh, "/proc/cmdline") { return $1 if <$fh> =~ /root=(\/\S+)/; } my $root = mnt2dev("/"); return $root if $root; return $& if `/usr/sbin/rdev` =~ /\/\S+/; return; } 1;