272 lines
7.0 KiB
Perl
Executable File
272 lines
7.0 KiB
Perl
Executable File
#!/usr/bin/perl -w
|
|
#
|
|
# Helper script for debian-cd EFI CD creation
|
|
#
|
|
# Parse the Isolinux boot menus and create matching grub menus and submenus
|
|
#
|
|
# Complicated by the way grub theming works - we need to create a
|
|
# separate grub theme per submenu simply so that we can describe the
|
|
# current (sub)menu appropriately.
|
|
|
|
use strict;
|
|
use File::Path qw(make_path);
|
|
|
|
my $isolinuxdir = shift or die "Need to know where the isolinux directory is!\n";
|
|
my $outdir = shift or die "Need to know where to write output!\n";
|
|
my $grub_theme = shift or die "Need input file location for base grub theme!\n";
|
|
my $tl_distro= shift or die "Need a top-level distro name (e.g. Debian)\n";
|
|
my $tl_kernel= shift or die "Need a top-level kernel (e.g. GNU/Linux)\n";
|
|
my $tl_version= shift or die "Need a top-level version (e.g. 7.0)\n";
|
|
my $theme_dir = "$outdir/boot/grub/theme";
|
|
my @cpp_and_opts = ('cpp',
|
|
'-traditional',
|
|
'-undef',
|
|
'-P',
|
|
'-C',
|
|
'-Wall',
|
|
'-nostdinc');
|
|
|
|
my @lines;
|
|
my @menus;
|
|
my $incdepth = 0;
|
|
my @menu_number = (1,0,0,0,0);
|
|
my @menu_title = ('', '', '', '', '');
|
|
my $menudepth = 0;
|
|
my $pre = "";
|
|
my $in_ifcpu = 0;
|
|
my $amd64_label = "";
|
|
my %menu;
|
|
|
|
sub parse_file {
|
|
my $file = shift;
|
|
|
|
$incdepth++;
|
|
# for(my $i = 0; $i < $incdepth ; $i++) {
|
|
# print STDERR " ";
|
|
# }
|
|
# print STDERR "parsing $isolinuxdir/$file\n";
|
|
open(my $fh, "< $isolinuxdir/$file") or return;
|
|
while (my $line = <$fh>) {
|
|
chomp $line;
|
|
if ($line =~ /^\s*include\ (.*\.cfg)/) {
|
|
parse_file($1);
|
|
} elsif ($line =~ /label archdetect/) {
|
|
# We don't have support for arch detection in Grub, so only
|
|
# show the amd64 options
|
|
$in_ifcpu = 1;
|
|
} elsif ($line =~ /kernel (.*c32)/) {
|
|
# This tells us that the matching "append" data will have
|
|
# the label we need to look for. Ugh!
|
|
if ($1 =~ /ifcpu64/) {
|
|
$in_ifcpu = 2;
|
|
}
|
|
} elsif ($line =~ /^\s*label (.*)/ && $1 =~ /$amd64_label/) {
|
|
$in_ifcpu = 3;
|
|
} elsif ($line =~ /^\s*append\ (.*\.cfg)/) {
|
|
if ($in_ifcpu == 3) {
|
|
parse_file($1);
|
|
$in_ifcpu = 1;
|
|
} else {
|
|
push(@lines, $line);
|
|
}
|
|
} elsif ($line =~ /append (.*)$/ && $in_ifcpu == 2) {
|
|
# Parse out the first entry - that's what we want to use
|
|
# as a label elsewhere. Ugh!
|
|
my @list = split(/ /, $1);
|
|
$amd64_label = $list[0];
|
|
$in_ifcpu = 1;
|
|
} elsif ($line =~ /default archdetect/) {
|
|
$in_ifcpu = 0;
|
|
} else {
|
|
push(@lines, $line);
|
|
}
|
|
}
|
|
close $fh;
|
|
$incdepth--;
|
|
}
|
|
|
|
sub print_indent {
|
|
my $text = shift;
|
|
my $i = 1;
|
|
while ($i++ < $menudepth) {
|
|
print " ";
|
|
}
|
|
print $text;
|
|
}
|
|
|
|
sub print_kernel {
|
|
my $t = shift;
|
|
my %k = %{$t};
|
|
my $initrd;
|
|
my $hotkey = "";
|
|
|
|
if ($k{"label"} =~ m,\^(\S),) {
|
|
$hotkey = lc "--hotkey=$1 ";
|
|
$k{"label"} =~ s/\^//;
|
|
}
|
|
if ($k{"append"} =~ s? (initrd=\S+)??) {
|
|
$initrd = $1;
|
|
$initrd =~ s?^.*initrd=??;
|
|
}
|
|
print_indent "menuentry $hotkey'$pre" . $k{"label"} . "' {\n";
|
|
print_indent " set background_color=black\n";
|
|
print_indent " linux " . $k{"kernel"} . " " . $k{"append"} . "\n";
|
|
print_indent " initrd $initrd\n";
|
|
print_indent "}\n";
|
|
}
|
|
|
|
sub debug {
|
|
# print_indent $menudepth . " " . $menu{"number"} . ": " . $menu{"label"} .
|
|
# " '" . $menu{"title"} . "'\n";
|
|
}
|
|
|
|
sub create_theme_file {
|
|
my $filename = shift;
|
|
my @args;
|
|
push(@args, @cpp_and_opts);
|
|
push(@args, "-DTITLE=\"$tl_distro $tl_kernel $tl_version\"");
|
|
for (my $i = 0; $i < $menudepth; $i++) {
|
|
push(@args, "-DMENU$i=\"" . $menu_title[$i] . "\"");
|
|
}
|
|
push(@args, "$grub_theme");
|
|
open(IN, "-|", @args) or die "Can't open cpp input: $!\n";
|
|
open(OUT, ">", "$theme_dir/$filename")
|
|
or die "Can't create theme file $theme_dir/$filename: $!\n";
|
|
while (<IN>) {
|
|
print OUT "$_";
|
|
}
|
|
close(IN);
|
|
close(OUT);
|
|
open(IN, "<", "$theme_dir/$filename");
|
|
open(OUT, ">", "$theme_dir/dark-$filename");
|
|
while (<IN>) {
|
|
next if ($_ =~ /^desktop-image:/);
|
|
print OUT "$_";
|
|
}
|
|
close(IN);
|
|
close(OUT);
|
|
}
|
|
|
|
make_path($theme_dir);
|
|
if (! -d $theme_dir) {
|
|
die "Can't make theme dir $theme_dir: $!\n";
|
|
}
|
|
parse_file("isolinux.cfg");
|
|
|
|
$menu{"number"} = "1";
|
|
$menu{"label"} = "top";
|
|
$menu{"title"} = "$tl_distro $tl_kernel UEFI Installer menu";
|
|
$menu_title[$menudepth] = $menu{"title"};
|
|
|
|
my %kernel;
|
|
my $in_kernel = 0;
|
|
my $in_dark = 0;
|
|
my $new_menu = 0;
|
|
|
|
$menudepth++;
|
|
debug();
|
|
print_indent "set theme=/boot/grub/theme/" . $menu{"number"} . "\n";
|
|
create_theme_file($menu{"number"});
|
|
|
|
foreach my $line(@lines) {
|
|
if ($line =~ /^\s*menu begin\ (\S+)/) {
|
|
$menu_number[$menudepth]++;
|
|
$new_menu = 1;
|
|
my $mn_string = "";
|
|
for(my $i = 0; $i <= $menudepth ; $i++) {
|
|
$mn_string .= "$menu_number[$i]";
|
|
if ($i < $menudepth) {
|
|
$mn_string .= "-";
|
|
}
|
|
}
|
|
$menu{"number"} = $mn_string;
|
|
$menu{"label"} = $1;
|
|
if ($menu{"label"} eq "dark") {
|
|
$in_dark = 1;
|
|
}
|
|
if ($in_kernel) {
|
|
print_kernel(\%kernel);
|
|
undef %kernel;
|
|
$in_kernel = 0;
|
|
}
|
|
} elsif ($line =~ /^\s*menu end/) {
|
|
if ($in_kernel) {
|
|
print_kernel(\%kernel);
|
|
undef %kernel;
|
|
$in_kernel = 0;
|
|
}
|
|
$menu_number[$menudepth] = 0;
|
|
$menudepth--;
|
|
if ($menudepth) {
|
|
print_indent "}\n";
|
|
}
|
|
if ($menudepth > 1) {
|
|
$pre = "... ";
|
|
} else {
|
|
$pre = "";
|
|
$in_dark = 0;
|
|
}
|
|
} elsif ($line =~ /^\s*menu title (.*$)/) {
|
|
if ($in_kernel) {
|
|
print_kernel(\%kernel);
|
|
undef %kernel;
|
|
$in_kernel = 0;
|
|
}
|
|
$menu{"title"} = $1;
|
|
if ($new_menu) {
|
|
my $hotkey = "";
|
|
if ($menu{"label"} =~ m,\^(\S),) {
|
|
$hotkey = lc "--hotkey=$1 ";
|
|
$menu{"label"} =~ s/\^//;
|
|
}
|
|
print_indent "submenu $hotkey'$pre" . $menu{"label"} . " ...' {\n";
|
|
$menu_title[$menudepth] = $menu{"title"};
|
|
$menudepth++;
|
|
if ($menudepth > 1) {
|
|
$pre = "... ";
|
|
} else {
|
|
$pre = "";
|
|
}
|
|
debug();
|
|
if ($in_dark) {
|
|
print_indent "set menu_color_normal=white/black\n";
|
|
print_indent "set menu_color_highlight=yellow/black\n";
|
|
print_indent "set color_normal=white/black\n";
|
|
print_indent "set color_highlight=yellow/black\n";
|
|
print_indent "background_image\n";
|
|
print_indent "set theme=/boot/grub/theme/dark-" . $menu{"number"} . "\n";
|
|
} else {
|
|
print_indent "set menu_color_normal=cyan/blue\n";
|
|
print_indent "set menu_color_highlight=white/blue\n";
|
|
print_indent "set theme=/boot/grub/theme/" . $menu{"number"} . "\n";
|
|
}
|
|
print_indent "set gfxpayload=keep\n";
|
|
create_theme_file($menu{"number"});
|
|
$new_menu = 0;
|
|
}
|
|
} elsif ($line =~ /^[ \t]*label (\S*(rescue|install|auto|expert)\S*)/) {
|
|
if ($in_kernel) {
|
|
print_kernel(\%kernel);
|
|
undef %kernel;
|
|
}
|
|
$kernel{"ref"} = $1;
|
|
$in_kernel = 1;
|
|
} elsif ($line =~ /menu label (.*)$/ && $in_kernel) {
|
|
$kernel{"label"} = $1;
|
|
} elsif ($line =~ /menu label (.*)$/) {
|
|
$menu{"label"} = $1;
|
|
} elsif ($line =~ /menu default/ && $in_kernel) {
|
|
$kernel{"default"} = 1;
|
|
} elsif ($line =~ /kernel (.*)$/ && $in_kernel) {
|
|
$kernel{"kernel"} = $1;
|
|
} elsif ($line =~ /append (.*)$/ && $in_kernel) {
|
|
$kernel{"append"} = $1;
|
|
} else {
|
|
#print "$line\n";
|
|
}
|
|
}
|
|
if ($in_kernel) {
|
|
print_kernel(\%kernel);
|
|
undef %kernel;
|
|
}
|