#!/usr/bin/perl -w

#
# "SystemImager" - Copyright (C) 1999-2001 Brian Elliott Finley <brian@systemimager.org>
#
#   $Id: mkautoinstallcd,v 1.5.4.1 2001/11/30 04:19:00 dannf Exp $
#
#   Written by Brian Elliott Finley <brian@systemimager.org>
#

#print <<'EOF';

#makeautoinstallcd has been renamed to 
#  "mkautoinstallcd"

use Getopt::Long;
use AppConfig;

my $config = AppConfig->new(
			    'autoinstall_script_dir' => { ARGCOUNT => 1 },
			    'autoinstall_boot_dir' => { ARGCOUNT => 1 },
			    'default_imagedir' => { ARGCOUNT => 1 },
			    'rsyncd_conf' => { ARGCOUNT => 1 },
			    'config_dir' => { ARGCOUNT => 1 },
			    );
$config->file('/etc/systemimager/systemimager.conf');

my $autoinstall_boot_dir = $config->autoinstall_boot_dir();

# this can be changed as more architectures are added
$autoinstall_boot_dir = $autoinstall_boot_dir . "/i386-boot";

if (!$autoinstall_boot_dir) {
    die "AUTOINSTALL_BOOT_DIR not defined in the config file.";
}

### END parse the config file ###

# set shell PATH for system() calls 
$ENV{PATH} = "/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin";

$version_number="2.0.1";
$program_name = "mkautoinstallcd";
$version_info = <<"EOF";
$program_name (part of SystemImager) v$version_number
    
Copyright (C) 1999-2001 Brian Elliott Finley <brian\@systemimager.org>
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
EOF

$help_info = $version_info . <<"EOF";

Usage: $program_name [OPTION]... -out-file FILE_NAME

Options: (options can be presented in any order and may be abbreviated)
 -help             Display this output.
 -version          Display version and copyright information.
 -out-file FILE    Name of the file that will hold the resulting ISO image.
                   (Not to worry, this will only be about 3 MB in size.)
 -quiet            Don\'t print any output, just provide an appropriate 
                   exit code.

Download, report bugs, and make suggestions at:
http://systemimager.org/
EOF

GetOptions( 
            "out-file=s" => \$iso_file,
            "help" => \$help,
            "version" => \$version,
            "quiet" => \$quiet 
) || die "$help_info";

# if requested, print help information
if($help) { 
  print "$help_info";
  exit 0;
}

# if requested, print version and copyright information
if($version) {
  print "$version_info";
  exit 0;
}

# search for CD creation tools
$cd_creation_tools="";
@files = ( "mkhybrid", "mkisofs");
foreach my $file ( @files ) {
  $command = "which $file > /dev/null 2>&1";
  $rc = 0xffff & system($command);
  if ($rc == 0) {
    # Compile a list of available tools -- we can choose which of the 
    # available ones we prefer later.
    $cd_creation_tools="$cd_creation_tools $file";
  }
}   

# if we didn't find any CD creation tools, error out
unless($cd_creation_tools) {
  my $unavailable_tools = "";
  foreach my $file ( @files ) {
    $unavailable_tools = "$unavailable_tools $file"
  }
  die   "FATAL: Coudn't find any of these CD creation tools: $unavailable_tools.\n";
}

# verify that a valid filename was specified
unless ($iso_file) { die "$help_info"; }
$command = "touch $iso_file > /dev/null 2>&1";
system("$command");
if($? != 0) { 
    unless ($quiet) {
        die "FATAL: Couldn't create $iso_file!\n";
    } else {
        exit 1;
    }
}

# Verify that the kernel and initrd.gz actually exist.
# Suggested by Greg Pratt <gpratt@valinux.com>.
@files = ( "$autoinstall_boot_dir/kernel", "$autoinstall_boot_dir/initrd.gz");
foreach my $file ( @files ) {
  unless ( -e "$file" ) {
    die "FATAL: I can't find $file!";
  }
}

# if not run as root, this script will surely fail
unless($< == 0) { die "FATAL: Must be run as root!\n"; }

# set some variables
$temp_dir = "/tmp/systemimager.autoinstallcd.temp.dir";
$temp_file = "$temp_dir/boot/vasiboot.img";
$mount_dir = "$temp_dir/mnt";
$boot_dir = "$temp_dir/boot";

# if $iso_file is not an absolute path, get current working directory and pre-pend
$_ = $iso_file;
unless (/^\//) {
	open(CWD, "pwd|");
        	$working_directory = <CWD>;
        	chomp $working_directory;
	close(CWD);
	$iso_file = "$working_directory/$iso_file";
}

# create temporary working directory
unless ($quiet) { print "Creating temporary working directory...\n"; }
$command = "rm -fr $temp_dir";
system("$command");
if($? != 0) { die "FATAL: \"$command\" failed!\n"; }
mkdir $temp_dir, 0770 or die "FATAL: Couldn't create temporary working directory $mount_dir!\n";
mkdir $mount_dir, 0770 or die "FATAL: Couldn't create temporary working directory $mount_dir/mnt!\n";
mkdir $boot_dir, 0770 or die "FATAL: Couldn't create temporary working directory $mount_dir/boot!\n";

# create temporary image
$command = "dd if=/dev/zero of=$temp_file bs=1k count=2880";
unless ($quiet) {
    system("$command");
} else {
    system("$command > /dev/null 2>&1");
}
if($? != 0) { die "FATAL: \"$command\" failed!\n"; }

# create dos filesystem on temporary image
$command = "mkdosfs $temp_file";
unless ($quiet) {
    print "Creating DOS filesystem on temporary image...\n";
    system("$command");
} else {
    system("$command > /dev/null 2>&1");
}
if($? != 0) { die "FATAL: Couldn't create DOS filesystem on $temp_file!\n"; }

# Run syslinux *before* copying files to prevent syslinux from partially 
# overwriting the first large on the diskette image.  Bad syslinux, bad!
if (!$quiet) {print "Using \"syslinux\" to make CD image bootable...\n";}
$command = "syslinux -s $temp_file";
system("$command");
if($? != 0) { die "FATAL: \"$command\" failed!\n"; }

# mount the freshly created filesystem
unless ($quiet) { print "Mounting temporary image in loopback mode...\n"; }
$command = "mount -t msdos -o loop $temp_file $mount_dir";
system("$command");
if($? != 0) { die "FATAL: Couldn't mount temporary image in loopback mode!\n"; }

# copy stuff to image
foreach $file ( "$autoinstall_boot_dir/initrd.gz",
		"$autoinstall_boot_dir/kernel",
		"$autoinstall_boot_dir/pxelinux.cfg/syslinux.cfg",
		"$autoinstall_boot_dir/pxelinux.cfg/message.txt") {
    unless ($quiet) {print "Copying $file to temporary image...\n";}
    $command = "cp -f $file $mount_dir";
    system("$command");
    if($? != 0) { die "FATAL: Couldn't copy $file to $mount_dir!\n"; }
}

# unmount temporary image
unless ($quiet) {print "Un-mounting temporary image...\n";}
$command = "umount $mount_dir && rm -fr $mount_dir";
system("$command");
if($? != 0) { die "FATAL: Couldn't un-mount temporary from $mount_dir/tmp!\n"; }

# compile iso image creation command
if($cd_creation_tools =~ /mkhybrid/) {
  $command = "cd $temp_dir && mkhybrid -b boot/vasiboot.img -c boot/boot.catalog -A systemimager-autoinstallcd-$version_number -p \"Created by makeautoinstallcd -- part of SystemImager\.  http://systemimager.org/\" -o $iso_file .";
} elsif($cd_creation_tools =~ /mkisofs/) {
  $command = "cd $temp_dir && mkisofs -b boot/vasiboot.img -c boot/boot.catalog -o $iso_file .";
}

# execute iso image creation command
unless ($quiet) {
    system("$command");
} else {
    system("$command > /dev/null 2>&1");
}
if($? != 0) { die "FATAL: \"$command\" failed!\n"; }

# get rid of temporary directory
unless ($quiet) { print "Removing temporary mount point...\n";}
$command = "rm -fr $temp_dir";
system("$command");
if($? != 0) { die "FATAL: Couldn't remove temporary working directory!\n"; }

# print done!
unless ($quiet) { print "Done!\n"; }
unless ($quiet) { print "\nYou can now burn your ISO image to a CDROM with a command such as:\n"; }
unless ($quiet) { print qq("cdrecord -v speed=2 dev=1,0,0 $iso_file"\n); }
unless ($quiet) { print "\nSee the cdrecord manual for more information. (\"man cdrecord\")\n"; }

exit 0;
