#!/usr/bin/perl -w

#----------------------------------------------------------------------
# copyright (C) 2002 Mitel Networks Corporation
# 
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# 		
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 		
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
# 
# Technical support for this program is available from Mitel Networks 
# Please visit our web site www.e-smith.com for details.
#----------------------------------------------------------------------

=head1 NAME

floppy-put-image - create a reinstallation floppy

=head1 SYNOPSIS

Called from "signal-event reinstall-disk"

=head1 DESCRIPTION

The reinstallation floppy is designed to install the system and restore
the configuration database to allow a restore from tape or desktop to 
be performed. The main configuration database is stored on the floppy,
but all other database fragments are restored from the previous backup.

=head1 METHODS

=begin testing

my $out = `$^X -cw $Original_File 2>&1`;
is( $?, 0, 'compiles' );
is( $out, "$Original_File syntax OK\n", 'no warnings' );

=end testing

=cut

package esmith;

use strict;
use Errno;
use esmith::config;
use esmith::util;
use esmith::ConfigDB;

=begin testing

my $testing_dir = "30e-smith-reinstall-floppy";

$ENV{ESMITH_CONFIG_DB}   = "$testing_dir/configuration";
$ENV{ESMITH_MOTD}        = "$testing_dir/motd";
$ENV{ESMITH_RAIDTAB}     = "$testing_dir/raidtab";
$ENV{ESMITH_FLOPPY_PATH} = "$testing_dir";

unlink("$testing_dir/ks.cfg");

$ENV{ESMITH_TESTING_REINSTALL_FLOPPY} = 1;    # Skip writing the floppy
is(system("$^X $Original_File"), 0, "System command returned 0");

ok( (-f "$testing_dir/ks.cfg"), "ks.cfg file created");

open(WRITTEN, "$testing_dir/ks.cfg") or die "Couldn't read ks.cfg: $!\n";
my @written = <WRITTEN>;

open(EXPECTED, "$testing_dir/expected_raid_ks.cfg") 
    or die "Couldn't read expected_raid_ks.cfg: $!\n";
my @expected = <EXPECTED>;

is_deeply(\@written, \@expected, "Written raid ks.cfg matches expected");

$ENV{ESMITH_RAIDTAB}     = "$testing_dir/no_raidtab_file";

ok(unlink("$testing_dir/ks.cfg"), "Deleted ks.cfg again");

$ENV{ESMITH_TESTING_REINSTALL_FLOPPY} = 1;    # Skip writing the floppy
is(system("$^X $Original_File"), 0, "System command returned 0");

ok( (-f "$testing_dir/ks.cfg"), "ks.cfg file created");

open(WRITTEN, "$testing_dir/ks.cfg") or die "Couldn't read ks.cfg: $!\n";
@written = <WRITTEN>;

open(EXPECTED, "$testing_dir/expected_nonraid_ks.cfg") 
    or die "Couldn't read expected_nonraid_ks.cfg: $!\n";
@expected = <EXPECTED>;

is_deeply(\@written, \@expected, "Written nonraid ks.cfg matches expected");

=end testing

=cut

my $db = esmith::ConfigDB->open() or die "Couldn't open ConfigDB\n";

my @ks_contents = gather_ks_contents();

my $path = $ENV{ESMITH_FLOPPY_PATH} || "/etc/e-smith/floppy";

open (KS, ">$path/ks.cfg")
    or die "Can't open file $path/ks.cfg for write: $!\n";

print KS @ks_contents;

close (KS) or die "Can't close file $path/ks.cfg: $!\n";

exit 0 if $ENV{ESMITH_TESTING_REINSTALL_FLOPPY};

use constant FD_DEV => "/dev/fd0H1440";

system("/usr/bin/fdformat", FD_DEV) == 0
    or die "Could not format floppy disk. " .
	"Check system log for details\n";

system("/sbin/mkdosfs", FD_DEV) == 0
    or die "Could not DOS format floppy disk. " .
	"Check system log for details\n";

system("/usr/bin/syslinux", FD_DEV) == 0
    or die "Could not run syslinux on floppy disk. " .
	"Check system log for details\n";

mkdir "/var/tmp/mnt.$$" or die "Could not create temp mount directory: $!\n";

if (system("/bin/mount", "-o", "loop", "$path/boot.img", "/var/tmp/mnt.$$"))
{
    system("/bin/umount", "/var/tmp/mnt.$$");
    rmdir("/var/tmp/mnt.$$");
    die "Could not mount old boot image\n";
}

if (system("/bin/mount", FD_DEV, "/mnt/floppy"))
{
    system("/bin/umount", "/var/tmp/mnt.$$");
    rmdir("/var/tmp/mnt.$$");
    die "Could not mount floppy\n";
}

foreach my $file (qw(boot.msg  initrd.img  vmlinuz))
{
    if (system("/bin/cp", "/var/tmp/mnt.$$/$file", "/mnt/floppy"))
    {
	system("/bin/umount", "/var/tmp/mnt.$$");
	rmdir("/var/tmp/mnt.$$");
	system("/bin/umount", "/mnt/floppy");
	die "Could not copy $file to floppy\n";
    }
}

if (system("/bin/umount", "/var/tmp/mnt.$$"))
{
    rmdir("/var/tmp/mnt.$$");
    die "Could not umount loopback mount\n";
}

foreach my $file (qw(syslinux.cfg ks.cfg))
{
    if (system ("/bin/cp", "-f", "$path/$file", "/mnt/floppy"))
    {
	system ("/bin/umount /mnt/floppy");
	die "Could not copy file $path/$file " . 
	    "to the floppy\n";
    }
}

#------------------------------------------------------------
# Unmount the floppy drive
#------------------------------------------------------------

system ("/bin/umount /mnt/floppy") == 0
    or die "Can't unmount the floppy drive\n";

exit (0);

=head2 gather_ks_contents()

Gather all of the information to go into the ks.cfg file.
Returns an array containing the lines to be written to ks.cfg
=cut

sub gather_ks_contents
{

    my $format_raid = <<RAID;
zerombr yes
clearpart --all --initlabel
part raid.00 --size 100 --ondisk 0
part raid.01 --size 100 --ondisk 1
part raid.10 --size 500 --grow --ondisk 0
part raid.11 --size 500 --grow --ondisk 1
part raid.20 --size 256 --ondisk 0
part raid.21 --size 256 --ondisk 1
raid /boot raid.00 raid.01 --level 1 --device md0
raid /     raid.10 raid.11 --level 1 --device md1
raid swap  raid.20 raid.21 --level 1 --device md2
RAID

    my $format_nonraid = <<NONRAID;
zerombr yes
clearpart --all --initlabel
part  swap --size 256 
part /boot --fstype ext3 --size 100
part / --fstype ext3 --size 200 --grow 
NONRAID

    my $raidtab_file = $ENV{ESMITH_RAIDTAB} || '/etc/raidtab';

    my $partitions = (-e $raidtab_file) ? $format_raid : $format_nonraid;

    my $localtime = $db->get('TimeZone')->value || "US/Eastern";

    my $lilo = $db->get('lilo');

    my $addressMode = $lilo->prop('AddressMode') || "linear";

    my $config_file = $ENV{ESMITH_CONFIG_DB} || '/home/e-smith/configuration';

    open(CONFIGDB, $config_file) or die "Couldn't read $config_file\n";

    my $configdb = join('', <CONFIGDB>);
    chomp $configdb;
    $configdb =~ s:\\:\\\\:g;
    $configdb =~ s:\$:\\\$:g;

    my $motd_file = $ENV{ESMITH_MOTD} || '/etc/motd';

    my $motd = "Couldn't read $motd_file";

    $motd = join('', <MOTD>) if ( open(MOTD, $motd_file) );
    chomp $motd;

    my ($lang, $keyboard, $keytable) = $db->getLocale();

    my @contents = <<KS_END;
#----------------------------------------------------------------------
# kickstart file for SME Server V5
# Copyright (c) 2002 Mitel Networks Corporation
#----------------------------------------------------------------------
# NOTE: The only supported customizations to this file are:
#         keyboard
#         timezone
# To modify the default settings for these parameters, please refer 
# to the HOWTO document on http://www.e-smith.org/docs/howto/
#----------------------------------------------------------------------
    
cdrom
lang ${lang}
langsupport --default ${lang}
keyboard $keytable
network --bootproto static --ip 192.168.1.1 --netmask 255.255.255.0 --gateway 192.168.1.2 --nameserver 127.0.0.1

${partitions}

install
mouse none

timezone --utc ${localtime}
rootpw --iscrypted \$1\$G\$jWK/s8WgbjQJRyQUS3B0d1
auth --useshadow --enablemd5
bootloader --useLilo --location=mbr --${addressMode}
skipx

%packages
\@ Base

%post

# set up initial configuration
/sbin/e-smith/signal-event post-install

# SME Server configuration database parameters	
cat >/home/e-smith/configuration <<CONFIGDB_HERE
$configdb
CONFIGDB_HERE

# Force password set at reboot
/sbin/e-smith/db configuration set PasswordSet 'no'
# Force system reconfiguration at boot time
/sbin/e-smith/db configuration set bootstrap-console service status enabled
/sbin/e-smith/db configuration setprop bootstrap-console Run yes
/sbin/e-smith/db configuration setprop bootstrap-console ForceSave yes

# add comment to /etc/motd
cat >/etc/motd <<MOTD_HERE
$motd
MOTD_HERE

KS_END

    return @contents;
}
