A new user interface for you! Read more...

File cadameb-mkinitrd_setup of Package cadameb

#!/usr/bin/perl
#
# Install initrd scripts
#

use strict;
use Getopt::Long;

my @scripts_boot = ();
my @scripts_setup = ();
my %level_boot = ();
my %level_setup = ();
my %depends_boot = ();
my %depends_setup = ();
my %providedby_boot = ();
my %providedby_setup = ();

my $debug = 0;
my $offset = 0;
my $installdir = "/lib/mkinitrd";
my $scriptdir = "$installdir/scripts";
my $dohelp = 0;

my %stages = (
    setup => 0,
    filesystem => 1,
    crypto => 2,
    volumemanager => 3,
    softraid => 4,
    partitions => 5,
    devicemapper => 6,
    block => 7,
    device => 8,
    boot => 9,
);

sub dprintf
{
    if ($debug > 0) {
	printf @_;
    }
}

sub resolve_dependency
{
    my $section = shift(@_);
    my $name = shift(@_);
    my $oldlevel;
    my $level;
    my $depends;
    my $providedby;

    if ( $section eq "setup" ) {
	$level = \%level_setup;
	$depends = \%depends_setup;
	$providedby= \%providedby_setup;
    } else {
	$level = \%level_boot;
	$depends = \%depends_boot;
	$providedby= \%providedby_boot;
    }
    $oldlevel = $$level{$name};

    foreach my $elem (split(' ',$$depends{$name})) {
	my $newlevel = -1;

	foreach my $n (split(' ',$$providedby{$elem})) {
	    $newlevel = resolve_dependency($section, $n);
	    if ( $oldlevel <= $newlevel) {
		$oldlevel = $newlevel + 1;
	    }
	}

	if ($newlevel == -1) {
	    dprintf "Unresolved dependency \"%s\" ", $elem;
	}
    }
    dprintf "%s/%s (%s) ", $section, $name, $oldlevel;
    $$level{$name} = $oldlevel;

    return $oldlevel;
}

sub scan_section
{
    my @scripts = @_;
    my @scrlist = ();
    my $depends;
    my $level;
    my $providedby;

    SCAN: foreach $_ (@scripts) {
	my $provides;
	my $section;
	my $scriptname;
	my $level;
	my $depends;
	my $providedby;
	my $scrlist;

	if (/(.*)-(.*)\.sh$/) {
	    if (($1 ne "setup" ) && ($1 ne "boot")) {
		next SCAN;
	    }
	    $section = $1;
	    $scriptname = $2;
	} else {
	    next SCAN;
	}

	if ( $section eq "setup" ) {
	    $level = \%level_setup;
	    $depends = \%depends_setup;
	    $providedby= \%providedby_setup;
	    $scrlist = \@scripts_setup;
	} else {
	    $level = \%level_boot;
	    $depends = \%depends_boot;
	    $providedby= \%providedby_boot;
	    $scrlist = \@scripts_boot;
	}

	dprintf "scanning script %s (name %s)\n", $_, $scriptname;
	dprintf "\tsection: %s\n", $section;
	$provides = $scriptname;

	open(SCR, "$scriptdir/$_");

	while (<SCR>) {
	    chomp;
	    if ( /^\#%stage: (.*)/ ) {
		if (! defined $stages{$1}) {
		    dprintf "%s: Invalid stage \"%s\"\n", $scriptname, $1;
		    close(SCR);
		    next SCAN;
		}
		if ($section eq "setup") {
		    $$level{$scriptname} = ($stages{$1} * 10) + 1;
		} else {
		    $$level{$scriptname} = 91 - ($stages{$1} * 10);
		}
		dprintf "\tstage %s: %d\n", $1, $$level{$scriptname};
	    }
	    if ( /^\#%depends: (.*)/ ) {
		dprintf "\tdepends on %s\n", $1;
		$$depends{$scriptname} = $1;
	    }
	    if ( /\#%provides: (.*)/ ) {
		$provides = join(' ',$provides,$1);
	    }

	}
	close SCR;

	@$scrlist = (@$scrlist,$scriptname);

	dprintf "\tprovides %s\n", $provides;
	foreach my $elem (split(' ',$provides)) {
	    $$providedby{$elem} = join(' ', $$providedby{$elem},$scriptname);
	}
    }
}

sub usage {
    print <<EOF;
usage:
	mkinitrd_setup [-s|--scriptdir <scriptdir>]
		[-i|--installdir <installdir>]
		[-d|--debug] [-o|--offset <offset>] [-h|--help]

	Install mkinitrd scripts. Options are:
	-s|--scriptdir	Install initrd scripts from dir <scriptdir>
	-i|--installdir	Install initrd scripts in dir <installdir>
	-d|--debug	Enable debug output
	-o|--offset	Use <offset> between script numbers.

EOF
}

Getopt::Long::Configure('no_ignore_case');

if (!GetOptions('scriptdir|s=s' => \$scriptdir,
		'installdir|i=s' => \$installdir,
		'debug|d' => \$debug,
		'offset|o' => \$offset,
		'help|h' => \$dohelp
		)) {
    usage();
    exit 1;
}
if ( ! -d $installdir ) {
    print "Installation directory $installdir does not exist!\n";
    $dohelp++;
}
if ( $dohelp == 0 && ! -d "$installdir/setup" ) {
    print "Installation directory $installdir/setup does not exist!\n";
    $dohelp++;
}
if ( $dohelp == 0 && ! -d "$installdir/boot" ) {
    print "Installation directory $installdir/boot does not exist!\n";
    $dohelp++;
}
if ( $dohelp == 0 && ! -d $scriptdir ) {
    print "Script directory $scriptdir does not exist!\n";
    $dohelp++;
}
if ($dohelp > 0) {
    usage();
    exit 0;
}

print "Scanning scripts ...\n";
opendir(DIR, $scriptdir);
my @scripts = grep { /.*\.sh$/ && -f "$scriptdir/$_" } readdir(DIR);
closedir DIR;

# Scan scripts
scan_section(@scripts);

print "Resolve dependencies ...\n";
# Resolve dependencies
foreach my $scr (@scripts_setup) {
    resolve_dependency("setup", $scr);
    dprintf "\n";
}

foreach my $scr (@scripts_boot) {
    resolve_dependency("boot", $scr);
    dprintf "\n";
}

print "Install symlinks in $installdir/setup ...\n";
chdir "$installdir/setup" || die "Can't chdir to $installdir/setup : $!";

opendir(DIR, ".");
my @links = grep { -l "$_" } readdir(DIR);
closedir DIR;

foreach $_ (@links) {
    unlink || printf "Can't unlink %s: %s\n", $_, $!;
}

foreach (@scripts_setup) {
    my $level = \%level_setup;
    my $lvl = $$level{$_};
    my $linkname;
    my $target;
    my $ret;

    $linkname = sprintf "%02d-%s.sh", $lvl, $_;
    $target = sprintf "../scripts/setup-%s.sh", $_;
    # Strictly speaking not required, but ...
    next if -l $linkname;
    dprintf "Linking %s to %s\n", $target, $linkname;
    $ret = symlink($target, $linkname);
    if ( $ret < 1 ) {
	printf "Failed to create symlink %s: %s\n", $linkname, $!;
    }
}

print "Install symlinks in $installdir/boot ...\n";
chdir "../boot" || die "Can't chdir to $installdir/boot: $!";

opendir(DIR, ".");
@links = grep { -l "$_" } readdir(DIR);
closedir DIR;

foreach $_ (@links) {
    unlink || printf "Can't unlink %s: %s\n", $_, $!;
}

foreach (@scripts_boot) {
    my $level = \%level_boot;
    my $lvl = $$level{$_};
    my $linkname;
    my $target;
    my $ret;

    $linkname = sprintf "%02d-%s.sh", $lvl, $_;
    $target = sprintf "../scripts/boot-%s.sh", $_;
    # Strictly speaking not required, but ...
    next if -l $linkname;
    dprintf "Linking %s to %s\n", $target, $linkname;
    $ret = symlink($target, $linkname);
    if ( $ret < 1 ) {
	printf "Failed to create symlink %s: %s\n", $linkname, $!;
    }
}