123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226 |
- #!/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");
- }
|