mirror of
https://github.com/xcat2/xNBA.git
synced 2024-12-12 22:36:28 +00:00
227 lines
6.9 KiB
Perl
227 lines
6.9 KiB
Perl
|
#!/usr/bin/perl -w
|
||
|
#
|
||
|
# Perl script to make a bootable image from a floppyfw floppy
|
||
|
# The basic idea is to unpack and replace or convert all
|
||
|
# the necessary config files into the initrd
|
||
|
# and then make a bootable image out of it
|
||
|
#
|
||
|
# The --format= option overrides the default of nbi or elf hardcoded
|
||
|
# in the source. Valid arguments are nbi or elf.
|
||
|
#
|
||
|
# The --output= options specifies an output file instead of stdout
|
||
|
# The --nonet option specifies that a netbootable image is not to
|
||
|
# be built but the vmlinuz and initrd.gz files left behind in $tempdir
|
||
|
# The --localtime=f option specifies a timezone file that's to be
|
||
|
# copied to /etc/localtime in the initrd, allowing a different timezone.
|
||
|
# The --ffw29 option is intended for 2.9.x and above and extends
|
||
|
# the size of the initrd by making a bigger one and copying the original over.
|
||
|
#
|
||
|
# The first non-option argument is taken to be the letter of a floppy to
|
||
|
# convert, e.g. a:, b: or even x: where x: is mapped to a file using
|
||
|
# mtools mapping in $HOME/.mtoolsrc. See the mtools documentation.
|
||
|
# Thus you can work on a floppy image in a disk file and only write
|
||
|
# to a floppy with dd or cp when you need to test the image.
|
||
|
|
||
|
use Getopt::Long;
|
||
|
|
||
|
use lib '/usr/local/lib/mkffwnb/';
|
||
|
use Extendinitrd;
|
||
|
|
||
|
use strict;
|
||
|
|
||
|
use vars qw($testing $verbose $localtime $nonet $format $ffw29 $imagefile
|
||
|
$floppy $libdir $tftpdir $output $tempdir $tempmount);
|
||
|
|
||
|
sub findversion () {
|
||
|
my ($version) = grep(/FloppyFW/, `mtype $imagefile ${floppy}floppyfw.msg`);
|
||
|
return '' unless defined($version) and $version ne '';
|
||
|
chomp($version);
|
||
|
$version =~ s/.*FloppyFW (\d+\.\d+\.\d+(\.\d+)?).*/$1/;
|
||
|
return ($version);
|
||
|
}
|
||
|
|
||
|
sub getappendargs () {
|
||
|
my ($append) = join(' ', grep(/^\s*(append\s|console=)/, `mtype $imagefile ${floppy}syslinux.cfg`));
|
||
|
chomp ($append);
|
||
|
my @args = split(/\s+/, $append);
|
||
|
my @result = ();
|
||
|
foreach $_ (@args) {
|
||
|
next if (/^$/ or /^append/ or /^initrd=/);
|
||
|
next if (!$ffw29 and /^root=/);
|
||
|
push (@result, $_);
|
||
|
}
|
||
|
return (join(' ', @result));
|
||
|
}
|
||
|
|
||
|
# Copy whole floppy to the current directory
|
||
|
# m preserves timestamps, n overwrites without warning and / means recursive
|
||
|
sub mcopy ($) {
|
||
|
my ($tempdir) = @_;
|
||
|
|
||
|
print "mcopy $imagefile -mn/ ${floppy}* $tempdir\n";
|
||
|
my $status = system("mcopy -mn/ $imagefile ${floppy}* $tempdir");
|
||
|
return ($status / 256);
|
||
|
}
|
||
|
|
||
|
# Gunzip file, -f forces overwriting of uncompressed file
|
||
|
sub gunzip ($) {
|
||
|
my ($file) = @_;
|
||
|
|
||
|
print "Gunzipping $file\n" if ($verbose);
|
||
|
my $status = system('gunzip', '-f', $file);
|
||
|
return ($status / 256);
|
||
|
}
|
||
|
|
||
|
# Gzip file, -f forces overwriting of compressed file
|
||
|
sub gzip ($) {
|
||
|
my ($file) = @_;
|
||
|
|
||
|
print "Gzipping $file\n" if ($verbose);
|
||
|
my $status = system('gzip', '-9', '-f', $file);
|
||
|
return ($status / 256);
|
||
|
}
|
||
|
|
||
|
sub loopbackmount ($$) {
|
||
|
my ($file, $point) = @_;
|
||
|
|
||
|
print "Mounting $file on $point loopback\n" if ($verbose);
|
||
|
my $status = system('mount', '-o', 'loop', $file, $point);
|
||
|
return ($testing ? 0 : $status / 256);
|
||
|
}
|
||
|
|
||
|
sub loopbackumount ($) {
|
||
|
my ($point) = @_;
|
||
|
|
||
|
print "Umounting $point\n" if ($verbose);
|
||
|
my $status = system('umount', $point);
|
||
|
return ($testing ? 0 : $status / 256);
|
||
|
}
|
||
|
|
||
|
# Convert DOS CR-NL to Unix NL. $dst has implied prefix of $tempmount
|
||
|
# Use @output for temporary storage in case we write back to the same file
|
||
|
sub dostounix ($$) {
|
||
|
my ($src, $dst) = @_;
|
||
|
my @output = ();
|
||
|
|
||
|
$dst = "$tempmount/$dst";
|
||
|
print "Converting $src to $dst\n" if ($verbose);
|
||
|
unless (open(S, $src)) {
|
||
|
print "$src: $!\n";
|
||
|
return (0);
|
||
|
}
|
||
|
while (<S>) {
|
||
|
chomp;
|
||
|
tr /\015//d;
|
||
|
push(@output, $_);
|
||
|
}
|
||
|
close(S);
|
||
|
open(D, ">$dst") or return;
|
||
|
for $_ (@output) {
|
||
|
print D "$_\n";
|
||
|
}
|
||
|
close(D);
|
||
|
chmod(0755, $dst);
|
||
|
return (1);
|
||
|
}
|
||
|
|
||
|
sub bunzip2untar ($$) {
|
||
|
my ($file, $dir) = @_;
|
||
|
|
||
|
print "Unpacking $file into $dir\n" if ($verbose);
|
||
|
system("bunzip2 < $file | (cd $dir; tar xf -)");
|
||
|
}
|
||
|
|
||
|
$testing = $< != 0;
|
||
|
$verbose = 1;
|
||
|
$format = '';
|
||
|
$imagefile = '';
|
||
|
GetOptions('output=s' => \$output,
|
||
|
'nonet!' => \$nonet,
|
||
|
'localtime=s' => \$localtime,
|
||
|
'format=s' => \$format,
|
||
|
'ffw29!' => \$ffw29,
|
||
|
'ffw30!' => \$ffw29,
|
||
|
'i=s' => \$imagefile);
|
||
|
if (defined($output) and $output !~ m(^/)) {
|
||
|
my $d = `pwd`;
|
||
|
chomp($d);
|
||
|
$output = "$d/$output";
|
||
|
}
|
||
|
if ($imagefile) {
|
||
|
$imagefile = "-i $imagefile";
|
||
|
}
|
||
|
$libdir = '/usr/local/lib/mkffwnb';
|
||
|
$tftpdir = '/usr/local/var/tftpboot';
|
||
|
# default can also be 'elf'
|
||
|
$format = 'nbi' if ($format ne 'elf' and $format ne 'nbi');
|
||
|
$floppy = $#ARGV >= 0 ? $ARGV[0] : 'a:';
|
||
|
print <<EOF;
|
||
|
This program requires mtools, tar, bzip2, loopback mount in the kernel,
|
||
|
and root privileges to execute. Hope you have them.
|
||
|
EOF
|
||
|
my $version = &findversion();
|
||
|
$version ne '' or die "Cannot determine version\n";
|
||
|
print "Version $version\n";
|
||
|
my $append = &getappendargs();
|
||
|
$append = "--append='$append'" if $append ne '';
|
||
|
print "$append\n";
|
||
|
$libdir .= '/' . $version;
|
||
|
-d $libdir or die "Cannot find files for $version\n";
|
||
|
$tempdir = $nonet ? '/tmp/mkffwnb' : "/tmp/mkffwnb$$";
|
||
|
$tempmount = 'tmpmount';
|
||
|
mkdir($tempdir, 0755);
|
||
|
print "Copying files off floppy, please be patient...\n";
|
||
|
&mcopy($tempdir) == 0 or die "Mcopy failed, diskette problem?\n";
|
||
|
chdir($tempdir);
|
||
|
&gunzip('initrd.gz') == 0 or die "Gunzip of initrd.gz failed\n";
|
||
|
if ($ffw29) {
|
||
|
extendinitrd("initrd", 5760);
|
||
|
system("mv newinitrd initrd");
|
||
|
}
|
||
|
mkdir($tempmount, 0755);
|
||
|
&loopbackmount('initrd', $tempmount) == 0 or die "Loopback mount failed\n";
|
||
|
&dostounix("$libdir/linuxrc", "linuxrc") if (-r "$libdir/linuxrc");
|
||
|
unless (&dostounix("$libdir/floppyfw.ini", "floppyfw.ini")) {
|
||
|
&dostounix("floppyfw/floppyfw.ini", $ffw29 ? "etc/floppyfw.ini" : "floppyfw.ini");
|
||
|
}
|
||
|
&dostounix("config", $ffw29 ? "etc/config.prelogin" : "etc/config");
|
||
|
for my $i (glob('*.bz2 floppyfw/add.bz2 modules/*.bz2 packages/*.bz2')) {
|
||
|
&bunzip2untar($i, $tempmount);
|
||
|
}
|
||
|
for my $i (glob('packages/*.ini')) {
|
||
|
my $file = $i;
|
||
|
$file =~ s:packages/::;
|
||
|
&dostounix($i, "etc/$file");
|
||
|
}
|
||
|
&dostounix("hosts", "etc/hosts");
|
||
|
&dostounix("modules.lst", "etc/modules.lst");
|
||
|
&dostounix("network.ini", "etc/network.init");
|
||
|
&dostounix("firewall.ini", "etc/firewall.init");
|
||
|
&dostounix("syslog.cfg", "etc/syslog.conf");
|
||
|
&dostounix("packages/timeinfo", "etc/localtime");
|
||
|
system("cp -p licenses/* $tempmount/licenses/");
|
||
|
# This conditional code is for 1.1.2 and below
|
||
|
unless (glob('modules/*.bz2')) {
|
||
|
print "Copying additional modules\n" if ($verbose);
|
||
|
system("cp -p modules/* $tempmount/lib/modules/");
|
||
|
}
|
||
|
# If a timezone file has been specified, copy that onto initrd
|
||
|
if (defined($localtime)) {
|
||
|
if (-r $localtime) {
|
||
|
print "Copying $localtime to $tempmount/etc/localtime\n";
|
||
|
system("cp -p $localtime $tempmount/etc/localtime");
|
||
|
} else {
|
||
|
print "$localtime: $!\n";
|
||
|
}
|
||
|
}
|
||
|
&loopbackumount($tempmount) == 0 or die "Loopback umount failed\n";
|
||
|
&gzip('initrd') == 0 or die "Gzip of initrd failed\n";
|
||
|
if ($nonet) {
|
||
|
print "Floppyfw directory in $tempdir\n";
|
||
|
} else {
|
||
|
print "Calling mk$format-linux to make the netbootable image\n" if ($verbose);
|
||
|
$output = "$tftpdir/floppyfw-$version.nb" if (!defined($output));
|
||
|
system("mk$format-linux $append --output=$output vmlinuz initrd.gz");
|
||
|
system("rm -fr $tempdir");
|
||
|
}
|