#!/usr/bin/perl
##############################################################################################
# File:         nph-suse_image
# Description:  Build a AutoYAST bootimage
# Author:       Lee Mayes   ( email leem@hp.com )
# Created:      15 Jan 2003
# Language:     perl
# Package:      LinuxCOE
##############################################################################################
# © Copyright 2000-2009 Hewlett-Packard Development Company, L.P
#
# 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.,
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
##############################################################################################
# Create a bootable image
# Init  - Initalize interactive HTML
# Step1 - Create the YaST Info file
# Step2 - Create the loopback filesys,Insert YaST Info, cleanup
# Step3 - Copy YaST Info and boot image to ~ftp/pub/images
# Step4 - Cleanup & Create final HTML
##############################################################################################

use strict;

my $debug = 0;
my $nonav = 0;
use CGI;
my $qin = new CGI;
use lib qw (/usr/local/linuxcoe-sd/lib /usr/local/linuxcoe-sd/includes);
use binaries;
use sysdes_paths;
use LinuxCOE;
my $db = new LinuxCOE;
$db->debug($debug);
$db->nonav($nonav);
use COEHtml;
my $qout = new COEHtml;
my $defs = $qin->param('defs');
if ( $defs ) {
  $db->LoadDefs($defs);
}
if ( $db->def('PROFILE_DIR') ) { $db->profbase($db->def('PROFILE_DIR')) }
my $replay = 0;
if ($qin->param('action') eq 'replay') {
  print STDERR "Replay detected, disabling interactive HTML\n" if $debug;
  $db->def('FINAL_INTERACTIVE',0);
  $replay = 1;
  $nonav = 1;  # no need for lipstick
}
$db->InitDB;

# Disable interactive HTML if requested || SECURITY_LEVEL = SECURE
 
my $privpath = "image$$";
my $sec_level = $db->def('SECURITY_LEVEL');
if ( $sec_level eq 'SECURE' ) {
  $db->def('FINAL_INTERACTIVE',0);
  $db->def('FINAL_URL_METHOD','https://');
  my $path = $db->def('FINAL_ABS_PATH');
  if ( $path =~ /\/$/ ) { chop($path) }
  $db->def('FINAL_ABS_PATH',"$path/$privpath");
}
unless ( $db->def('FINAL_INTERACTIVE') ) { $qout->do_nothing(1) }

my @vars = qw(hostname ip method profile os waystation netmask 
              kbd lang timezone mouse gateway namesvr utc);    

my $docroot = $ENV{'DOCUMENT_ROOT'} || $db->def('HTDOCS');
my $iesux = 0;
my $htmlpath = $db->def('FINAL_WD_PATH');
$htmlpath = "$htmlpath/$privpath" if ( $sec_level eq 'SECURE' );
my $htmlfile;
my $info_filename = "info$$.txt";                # Custom linuxrc file
my $info_file = "$htmlpath/$info_filename";      # Full path to linuxrc info file
my $ks_filename = "autoyast.xml$$";              # Custom YaST Info
my $ks_file = "$htmlpath/$ks_filename";       	 # Full path to YaST Info file
my $age = 1800 || $db->def('AGE');		 # Delete images older than $age seconds..
my $custimg = "$htmlpath/img$$";             # Custom floppy image
my $imgmount = "$htmlpath/imagedir$$";       # Where I loopback /bin/mount $custimg
my $asset = $qin->param('asset');	     # Asset ID
my $initrdmount = "$htmlpath/initrddir$$";   # Where I loopback /bin/mount initrd
my $ftp_dir = $db->def('FINAL_ABS_PATH');    # Where to dropoff the images
my $mounted = 0;                             # Image is mounted (for cleanup)
my $ISO = 0;  		 		     # Create a ISO image vs. floppy(s)
if ( $qin->param('image') =~ /iso$/ ) { $ISO=1 }
my $arch = $db->clean_var($qin->param('arch'));

# Slurp in SIM stuff if in play
my ($serial,@serials);
if ( $db->def('SIM') ) {
  @serials = split(':::',$qin->param('serial'));
  $serial = shift(@serials);
}

my ($distro,$version) = split(' ',$db->clean_var($qin->param('os')));
my $method = $qin->param('method');
my $profile = $db->clean_var($qin->param('profile'));
my $waystation = $qin->param('waystation');
my $wayip = $db->get_ip($waystation);
my $ip = $qin->param('ip');
my $gw = $qin->param('gateway') || $ip;
my $nm = $qin->param('netmask');
my $ns = $qin->param('namesvr');
my $kbd=$qin->param('kbd');
my $mouse=$qin->param('mouse');
my $lang=$qin->param('lang');
my $timezone=$qin->param('timezone');
my $hostname = $qin->param('hostname');
my $interface = $qin->param('netdev');
$interface = $interface || 'eth0';
my ($path,$parts,@bundles,$rpms,$final,$patch_me,$patch_freq,@coe_bundles,$misc,$final_text,$patch_method,$bundle_error,$sum_this_image,$trig_img,$trig_conf);
my $msgtail = "0c[F1-Main] [F6-Local] [F7-Disk] [F8-SuSE] [F9-COE] [F10-Final]07\n";
# These versions have filesys initrd vs. cpio archive
my @fsinitrd = qw(SLES8 SLES9 9.0 9.1 9.2);

my @methods = $db->sw_methods($distro,$version,$arch);
my $APT=0;                                      # Use APT in post processing
my $YUM=0;                                      # Use YUM in post processing
if ( grep(/APT/,@methods) ) { $APT=1 }
if ( grep(/YUM/,@methods) ) { $YUM=1 }
print STDERR "\$APT=$APT, \$YUM=$YUM\n" if $debug;
my $BRAND = $db->def('BRANDING');

###### MAIN #######
&Init;    # start html
my ($passwd,$userpasswd) = &check_pass;
&Step1;   # Create info.txt
&Step2;   # Insert into initrd as info 
&Step3;   # Make it ftp'able
&Step4;   # Cleanup and create final HTML
###### End of MAIN #######

sub Step1 {

# OK kids, lets create the info file!!!!

  print STDERR "Entering Step1\n" if $debug;
  $qout->message("Creating autoYaST file");
  $qout->updatehtml(1);
  if ( $method ne 'CDROM' ) {
    $path = $db->show_os($distro,$version,$arch,$method,$waystation);
    unless ($path) {
      &end_it_now("$waystation is NOT exporting $distro $version via $method");
    }
  } elsif ( $method eq 'CDROM' ) {
# This makes all CDROM installs fetch coe_bundles from Atlanta...
    $waystation = $db->def('WAYSTATION');
  }

# Extract the profile from DB (profile)  or calling env (Custom) 

  if ( $profile ne 'Custom' ) {

    my ($b,$c);
    ($parts,$misc,$final,$rpms,$patch_me,$patch_freq,$c,$b,$patch_method) = $db->parse_profile($profile,$arch,$version,$distro);
    unless ($parts) {
      &end_it_now($db->errmsg . " No parts..");
    }
    $final_text = $final;
    @coe_bundles = @{$c};
    @bundles = @{$b};
# May have overridden parts/misc
    if ( $qin->param('override')  eq 'YES' ) {
       $parts = $qin->param('parts');
       $misc = $qin->param('misc');
    }
    $parts =~ s/
//g;
    $parts =~ s/^#.*$//gm;
    $parts =~ s/\n+/\n/gs;

  } else {

    $parts = $qin->param('parts');
    $misc = $qin->param('misc');
    $final = $qin->param('final');
    $rpms = $qin->param('rpms');
    @bundles = $qin->param('bundles');
    @coe_bundles = $qin->param('coe_bundles');
    $patch_me = $qin->param('patch_me');
    $patch_freq = $qin->param('patch_freq');
    $patch_method = $qin->param('patch_method');

  }
  # Strip out all the comments and formatting oddities
  $misc =~ s/
//g;
  $misc =~ s/^#.*$//gm;
  $misc =~ s/\n+/\n/gs;
  $final =~ s/
//g;
  $final =~ s/^#.*$//gm;
  $final =~ s/\n+/\n/gs;
  $rpms =~ s/
//g;
  $rpms =~ s/^#.*$//gm;
  $rpms =~ s/\n+/\n/gs;

# What you say let's generate the files, eh?

  unless ( -d $htmlpath ) { mkdir $htmlpath,0755 }
  open(INFO,">$info_file") ||
    &end_it_now("Cannot open $info_file for writing : $!\n");

  my $lmeth = lc($method);
  if (($distro eq 'OpenSUSE' ) && ( $version ge '10.3' ) || ($version =~ /11/ )) {    # BUG: Temp hardcode until I see how SLES swings
    my $inst = "install=${lmeth}://${wayip}${path}";
    $inst .= "?device=$interface" if ( $interface );
    print INFO "$inst\n";
  } else {
    print INFO "Serverdir: $path\n";
    print INFO "InstMode: $lmeth\n";
  }
  print INFO "Server: $wayip\n";
  print INFO "Textmode: 1\n";

# If static IP, spec it out

  if ( $ip ) {
    print INFO "HostIP: $ip\n";
    print INFO "Netmask: $nm\n";
    print INFO "Gateway: $gw\n";
    print INFO "Nameserver: $ns\n";
  }
  print INFO "Netdevice: $interface\n" if ($interface);

# If proxy is requested, honor it

  my $proxy = $qin->param('proxy');
  if ( $proxy ) {
    my ($http,$host,$port) = split(':',$proxy);
    $port =~ s/\/$//;  		# Drop trailing / from port if it exists...
    $host =~ s/\///g;		# Drop leading /'s from hostname
    print INFO "Proxy: $host\n";
    print INFO "ProxyPort: $port\n";
  }

# Want VNC?

  my $vnc_pass = $qin->param('VNC_Pass');
  my $vnc_pass1 = $qin->param('VNC_Pass');
  if ($vnc_pass) {
    if ( $vnc_pass ne $vnc_pass1 ) { &end_it_now("Your VNC passwords do not match!") }
    print INFO "VNC: 1\n";
    print INFO "VNCPassword: $vnc_pass\n";
  }
  if (( length($vnc_pass) < 6 ) && ( $vnc_pass )) {
    &end_it_now("Your VNC password is too short, must be at least 6 characters!");
  }
  close(INFO);


# Now, let's create the autoyast file

  open(KS,">$ks_file") ||
    &end_it_now("Cannot open $ks_file for writing : $!\n");

  my $template = $db->find_file("boot/autoyast-$version-$arch");
  unless ( $template ) { $template = $db->find_file("boot/autoyast-$version") }
  unless ( $template ) {
    if (($version =~ /SLES8/ ) || ( $version =~ /SLES9/ ) || ( $version eq '10.0' ) || ( $version =~ /^9/ )) {
      $template = $db->find_file("boot/autoyast");
    } else {
      $template = $db->find_file("boot/autoyast-patterns");
    }
  }
  open(IN,"$template") ||
    &end_it_now("Cannot find info autoyast template for $version $arch!");
  my $buf;
  while($buf=<IN>) {
    $buf =~ s/\@WAYIP\@/$wayip/; 
    $buf =~ s/\@ARCH\@/$arch/; 
    last if ( $buf =~ /# LinuxCOE TIME/);
    print KS $buf;
  }

# Now lets create the LANG/MOUSE/KYBD/etc. AutoYaST part
#        <hwclock>GMT</hwclock>
#        <timezone>US/Pacific</timezone>
  print KS "      <clock>\n";
  print KS "        <hwclock>GMT</hwclock>\n" if ( $qin->param('utc') eq 'Yes' );
  print KS "        <timezone>".$qin->param('timezone')."</timezone>\n";
  print KS "      </clock>\n";
  print KS "      <keyboard>\n        <keymap>".$qin->param('kbd')."</keymap>\n      </keyboard>\n";
  print KS "      <language>".$qin->param('lang')."</language>\n";
  print KS "      <mouse>\n        <id>".$qin->param('mouse')."</id>\n      </mouse>\n";

# Add software
  while(<IN>) {
    last if /# LinuxCOE SuSE BUNDLES/;
    print KS;
  }
  my $base = $qin->param('base');
  unless ($base) {
    my @newbund;
    foreach my $bundle (@bundles) {
      if ( $bundle =~ /^BASE:/ ) {
        $bundle =~ s/BASE: //;
        $base = $bundle;
      } else {
        push(@newbund,$bundle);
      }
    }
    @bundles = @newbund;
  }
  print KS "      <base>$base</base>\n" if $base;
  my $swtag = 'addon';
  if (( $version =~ /SLE[DS]10/ ) || ($version eq '10.2' )) { $swtag = 'pattern' } 
  if ( @bundles ) {
    print KS qq[      <${swtag}s config:type="list">\n];
    foreach my $bundle (@bundles) {
      print KS "        <$swtag>$bundle</$swtag>\n";
    }
    print KS "      </${swtag}s>\n";
  }
  if ($rpms) {
    print KS qq[      <packages config:type="list">\n];
    foreach my $rpm (split('\n',$rpms)) {
      print KS "        <package>$rpm</package>\n";
    }
    print KS "      </packages>\n";
  }

  while(<IN>) {
    last if /# LinuxCOE PARTITION/;
    print KS;
  }

# OK, it's disk drive time  # part_choice - Autopartition
  my $pc = $qin->param('part_choice');
  if ( $pc eq 'Autopartition' ) {
   print KS qq[    <partitioning config:type="list">\n      <drive>\n];
   print KS "        <device>$parts</device>\n        <use>all</use>\n";
   print KS qq[        <initialize config:type="boolean">true</initialize>\n        </drive>\n      </partitioning>\n];
  } elsif ( $pc eq 'Simple' ) {
   print KS qq[    <partitioning config:type="list">\n      <drive>\n];
   my $device = $qin->param('Device');
   print KS "        <device>$device</device>\n        <use>all</use>\n";
   print KS qq[        <initialize config:type="boolean">true</initialize>\n];
   print KS qq[        <partitions config:type="list">\n];
   for my $i (0 .. 9) {
     my $mount = $qin->param("mount$i");
     last unless ($mount);
     my $size = $qin->param("size$i"); 
     my $grow = $qin->param("grow$i");
     my $fstype = $qin->param("fstype$i");
     print KS "          <partition>\n";
     print KS "            <mount>$mount</mount>\n";
     if ( $grow ) {
       print KS "            <size>max</size>\n";
     } else {
       print KS "            <size>$size</size>\n";
     }
     print KS qq[            <filesystem  config:type="symbol">$fstype</filesystem>\n];
     print KS "          </partition>\n";
   }
   print KS "        </partitions>\n";
   print KS qq[     </drive>\n     </partitioning>\n];
  } else {
    print KS "$parts\n";
  }

  while(<IN>) { 
    last if /# LinuxCOE Config Options/;
    print KS;
  }

  my @seeds = ('A'..'Z','a'..'z');                  
  my $seed = $seeds[int(rand(52))] . $seeds[int(rand(52))];
  my $enc_pass = crypt($passwd,$seed);

  print KS qq[   <users config:type="list">
      <user>
         <username>root</username>
         <user_password>$enc_pass</user_password>
         <encrypted config:type="boolean">true</encrypted>
         <forename/>
         <surname/>
      </user>
];

  my $uname = $qin->param('User_Name');
  if ( $uname ) {
    my ($for,$sur) = split(' ',$qin->param('Real_Name'));
    my $enc_pass = crypt($userpasswd,$seed);
    print KS qq[      <user>
         <username>$uname</username>
         <user_password>$enc_pass</user_password>
         <encrypted config:type="boolean">true</encrypted>
         <forename>$for</forename>
         <surname>$sur</surname>	  	
         <fullname>$for $sur</fullname>
         <home>/home/$uname</home>
         <password_settings>
           <expire></expire>
           <flag></flag>
           <inact>-1</inact>
           <max>99999</max>
           <min>0</min>
           <warn>7</warn>
         </password_settings>
         <shell>/bin/bash</shell>
];
   if ( $version eq '9.2' ) {
     print KS "         <uid>1000</uid>\n";
     print KS "         <gid>100</gid>\n";
   }
   print KS "      </user>\n";
  }
  print KS "    </users>\n";
  print KS "    <networking>\n";
  if ( $ip ) {
    my ($h,@d) = split('\.',$hostname);
    my $dom = join('.',@d);
    my ($net,$bcast) = $db->network_bcast($ip,$nm);
    print KS qq[
      <dns>
        <dhcp_hostname config:type="boolean">false</dhcp_hostname>
        <dhcp_resolv config:type="boolean">false</dhcp_resolv>
        <domain>$dom</domain>
        <hostname>$h</hostname>
        <nameservers config:type="list">
          <nameserver>$ns</nameserver>
        </nameservers>
        <searchlist config:type="list">
          <search>$dom</search>
        </searchlist>
      </dns>
      <interfaces config:type="list">
        <interface>
          <bootproto>static</bootproto>
          <broadcast>$bcast</broadcast>
          <device>$interface</device>
          <ipaddr>$ip</ipaddr>
          <netmask>$nm</netmask>
          <network>$net</network>
          <startmode>onboot</startmode>
        </interface>
      </interfaces>
      <modules config:type="list">
        <module_entry>
          <device>$interface</device>
          <module></module>
          <options></options>
        </module_entry>
      </modules>
      <routing>
        <ip_forward config:type="boolean">false</ip_forward>
        <routes config:type="list">
          <route>
            <destination>default</destination>
            <device>-</device>
            <gateway>$gw</gateway>
            <netmask>-</netmask>
          </route>
        </routes>
      </routing>
];
  } else {
    my $system = $qin->param('system') || 'linux';
    print KS qq[      <dns>
        <dhcp_hostname config:type="boolean">true</dhcp_hostname>
        <dhcp_resolv config:type="boolean">true</dhcp_resolv>
        <domain>local</domain>
        <hostname>$system</hostname>
      </dns>
      <interfaces config:type="list">
        <interface>
          <bootproto>dhcp</bootproto>
          <device>$interface</device>        
          <startmode>onboot</startmode>
        </interface>
      </interfaces>
];
  }
  print KS "    </networking>\n";
  while(<IN>) {
    last if /# LinuxCOE FINAL SCRIPT/;
    print KS;
  }

# Print Script Header
  print KS qq{        <script>
          <filename>final</filename>
          <interpreter>perl</interpreter>
          <source>
<![CDATA[
};

# Newer SuSE disables the nic during %post, go figure

    my $downit = 0;
    my @oks = qw(SLES8 9.0 9.1);
    unless (grep(/^$version/,@oks)) {
       $downit = 1;
       print KS qq[#Find a nic to activate for %post install
my \$nic;
opendir(DIR,"/etc/sysconfig/network");
foreach my \$file (readdir(DIR)) {
  next unless (\$file =~ /^ifcfg-eth/);
  print "Found \$file -";
  \$file =~ s/^ifcfg-//;
  \$nic = \$file;
  last;
}
closedir(DIR);
print " calling /sbin/ifup \$nic!\\n";
system "/sbin/ifup \$nic";
open(NIC,">/tmp/nic");
print NIC "\$nic\\n";
close(NIC);
];

    }

  &Add_COE_Hooks unless ($db->def('NO_COE'));

  print KS qq{]]>
          </source>
        </script>
};

# Add Final Script

    print KS qq{        <script>
          <filename>final-user</filename>
          <interpreter>shell</interpreter>
          <source>
<![CDATA[
};
    if ( $version eq 'SLES8' ) {
# SLES 8 didn't support perl, so fake it out - looks like SP3 it does!
    } elsif (( $distro eq 'SuSE' ) && ( $version eq '9.1' )) {

# SuSE sets keyboard type in X11 to 'de' regardless of lang.  Hack around this in final
      my %X11;
      my $infile = $db->find_file("data/X11-map-SuSE-$version-$arch");
      unless ( $infile ) {
        $infile = $db->find_file("data/X11-map-SuSE");
      }
      open(X11,"$infile");
      while(<X11>) {
        chomp;
        my($lang,$val) = split;
        $X11{$lang} = $val;
      }
      close(X11);
      my $lang = $qin->param('kbd');
      my $x_kbd = $X11{$lang} || "us";
      print KS qq[            /bin/cp /etc/X11/XF86Config /tmp/XF86Config.back
            /usr/bin/sed -e 's/XkbLayout"\\t"de/XkbLayout"\\t"$x_kbd/' </tmp/XF86Config.back >/etc/X11/XF86Config];
    }
    print KS qq{
            echo "AuotYaST-installed $distro $version - $BRAND `/bin/date`" > /etc/motd
};
    if (( $distro eq 'SuSE' ) && ( $version eq '9.0' )) {
        print KS qq{echo "You may optionally run 'configx' to configure your system for graphical login and use." >>/etc/motd
};
    }

# Create a file with parms we were created with

  foreach my $parm ($qin->param) {
    next if ( $parm =~ /Pass/i );
    next if ( $parm eq 'parts' );
    next if ( $parm eq 'misc' );
    my $val = $qin->param($parm);
    $parm=uc($parm);
    print KS "echo $parm=\\\"$val\\\" >>/etc/opt/LinuxCOE/args\n";
  }

    if ( $final ) {
      print KS "$final\n";
    }
    print KS qq{if [ -r "/tmp/nic" ]
  then
NIC=`cat /tmp/nic`
  /sbin/ifdown \$NIC
fi
};
    print KS qq{]]>
          </source>
        </script>
} if ( $downit );

  while(<IN>) { print KS }
  close(IN);
  close(KS);

} # End of Step1 - YaST Info is built!

sub Step4 {

# It's done, parse ks_help.html and create final page

  my $title = "$BRAND Custom Image - Completed";
  $qout->persist($title);
  $qout->message("Your image is now ready for retrieval!");

# Who am I?

  my $host = `/bin/hostname`;
  chomp $host;
  my $hostname = $db->def('HOSTNAME') || (gethostbyname($host))[0];

  my ($image_type,$target,$ks_path,$img_path,$info_path);
  if ( $ISO ) {
     $image_type = 'ISO';
     $target = "img$$.iso";
  } else {
     $image_type = 'IMG';
     $target = "boot$$.img";
  }
  if ( $sec_level eq 'SECURE' ) {
   $img_path = "$privpath/$target";
   $ks_path = "$privpath/$ks_filename";
   $info_path = "$privpath/$info_filename";
  } else {
   $img_path = $target;
   $ks_path = $ks_filename;
   $info_path = $info_filename;
  }
  my $warnings;
  if ( $bundle_error ) {
    $warnings = qq[<P><B><font color=red>Warning:</font></B> One or more bundles you requested have no RPMS associated with them!</P>];
  }
  if (( ! $qin->param('ip') ) && ( $method ne 'CDROM')) {
    $warnings .= qq[ <P><B>Warning:</B> Since you do not have static network information, you <B>MUST</B> have a working <B>DHCP</B> server on your subnet!</P>];
  }

  my %sr_array = (
    COE_WAYSTATION => $hostname,
    WAYSTATION => $waystation,
    KS_NAME => $ks_filename,
    KS_PATH => $ks_path,
    IMG_PATH => $img_path,
    IMG_NAME => $target,
    LINUXCOE_WARNINGS => $warnings,
    INFO_NAME => $info_filename,
    INFO_PATH => $info_path,
    MOD_IMG => "modules1-$$",
    INSTALL_PATH => $path,
  );
  if ($replay) {
    print STDERR "replay detected, emebedding data\n" if $debug;
    my $method = $db->def('FINAL_URL_METHOD') || 'ftp://';
    my $path = $db->def('FINAL_URL_PATH');
    my $url = "${method}${hostname}${path}${img_path}";
    my $msg = "START_OF_LINUXCOE_BEAM_DATA\n";
    $msg .= "$url\n";
    $msg .= "END_OF_LINUXCOE_BEAM_DATA\n";
    print "\n$msg\n";
    print $qin->end_html;
    exit;
  }
  my $msg = $db->Create_Final_HTML($distro,$version,$arch,'YAST',$image_type,$sec_level,$htmlpath,$sum_this_image,$serial,%sr_array);
  print STDERR "Calling CleanUp($htmlpath,$ftp_dir,$distro,$version,$arch,$trig_img,$trig_conf)\n" if $debug;
  $db->CleanUp($htmlpath,$ftp_dir,$distro,$version,$arch,$trig_img,$trig_conf);
  if ( $db->def('FINAL_INTERACTIVE') ) {
    $msg .= "\n</body></html>\n";
    $qout->trailer("$msg\n");
    $qout->updatehtml(0);
  } else {
    print $qin->header;
    $db->ShowNav($title);
    print $msg;
    print $qin->end_html;
    $db->ShowFooter;
    exit;
  }

}

sub Step3 {

# Simply copy YaST Info and img file to ftp directory

  $qout->message("Step3 : Making it accessible");
  $qout->updatehtml(1);
  if ( $ftp_dir =~ /\/$/ ) { chop($ftp_dir) }  # Drop trailing / if it's there...
  if ( $db->def('SIM') ) {
    my $simdir = $db->def('SIM');
    &my_sys("/bin/mv $custimg $simdir/$serial/boot.iso");
    &my_sys("/bin/mv $ks_file $simdir/$serial/autoyast.xml");
    &my_sys("/bin/mv $info_file $simdir/$serial/info.txt");
    $trig_img = "$simdir/$serial/boot.iso";
    $trig_conf = "$simdir/$serial/autoyast.xml";
    open(SIM,">$simdir/$serial/CUSTOM_SETTINGS");
    my ($sver,$supdate) = split('-',$version);
    if ( $supdate ) {
      $supdate =~ s/^SP//;
      $sver .= ".$supdate";
    }
    my $sdist = $distro;
    if ( $distro eq 'SuSE' ) { undef($sdist) }
    print SIM "DISTRO=${sdist}$sver\n";
    print SIM "ARCH=$arch\n";
    print SIM "IFACE=$interface\n";
    close(SIM);
    &my_sys("/bin/ln -sf CUSTOM_SETTINGS $simdir/$serial/${serial}.dat");
    #set symlinks to the "real" directory
    foreach my $serial_sym (@serials){
      &my_sys("/bin/ln -sf $serial $simdir/$serial_sym");
      &my_sys("/bin/ln -sf CUSTOM_SETTINGS $simdir/$serial/${serial_sym}.dat");
    }
    open(ARGS,">$simdir/$serial/args");
    foreach my $parm ($qin->param) {
      next if ( $parm =~ /Pass/i );
      next if ( $parm eq 'parts' );
      next if ( $parm eq 'misc' );
      my $val = $qin->param($parm);
      $parm = uc($parm);
      print ARGS "$parm=\"$val\"\n";
    }
    close(ARGS);
  } elsif ( $ISO ) {
    &my_sys("/bin/mv $custimg ${ftp_dir}/img$$.iso") if ( $custimg ne "${ftp_dir}/img$$.iso" );
    $sum_this_image = "${ftp_dir}/img$$.iso";
    &my_sys("/bin/mv $ks_file ${ftp_dir}/$ks_filename") if ( $ks_file ne "${ftp_dir}/$ks_filename" );
    &my_sys("/bin/mv $info_file ${ftp_dir}/$info_filename") if ( $info_file ne "${ftp_dir}/$info_filename" );
    $trig_img = $sum_this_image;
    $trig_conf = "${ftp_dir}/$ks_filename";
  } else {
    &my_sys("/bin/mv $custimg ${ftp_dir}/modules1-$$") if ( $custimg ne "${ftp_dir}/modules1-$$" );
    &my_sys("/bin/mv $htmlpath/bootnet.$$ ${ftp_dir}/boot$$.img") if ( "$htmlpath/bootnet.$$" ne "${ftp_dir}/boot$$.img" );
    $sum_this_image = "${ftp_dir}/boot$$.img";
    &my_sys("/bin/mv $ks_file ${ftp_dir}/$ks_filename") if ( $ks_file ne "${ftp_dir}/$ks_filename" );
    &my_sys("/bin/mv $info_file ${ftp_dir}/$info_filename") if ( $info_file ne "${ftp_dir}/$info_filename" );
    $trig_img = $sum_this_image;
    $trig_conf = "${ftp_dir}/$ks_filename";
  }

}

sub Step2 {

  if (( $db->def('SIM') ) || ( $db->def('ASSET_URL') )){
    $db->Store_Conf($ks_file,$asset);
  }
  unless ( $db->def('CREATE_IMAGE') ) {
    $qout->persist("$BRAND $distro $version Template - Completed");
    $qout->message("Your template is now ready for retrieval!");
    my $msg = qq[
Configuation file has been created and stored <a href=/templates/$asset.txt>HERE</a>.
];
    $msg .= "\n</body></html>\n";
    $qout->trailer("$msg\n");
    $qout->updatehtml(0);
    exit;
  }

# Mount the virgin image (s)using loop driver, jam our ks and asst files in there...

  my $uid = $>;            	# What's my UID
  umask 000;
  my ($distro,$version) = split(' ',$qin->param('os'));

# Create mountpoint for image

  $qout->message("Creating loopback system for YaST Info insertion");
  $qout->updatehtml(1);
  mkdir("$imgmount",0766) ||
    &end_it_now("Cannot mkdir $imgmount : $!\n");
  unless ( -d "$imgmount" ) {
    &end_it_now("mkdir $imgmount failed?!?!?!\n");
  }
  my $defimage .= "$distro-${version}-$arch-";

  if ( $qin->param('image') eq 'default' ) {
    $defimage .= 'modules1';
  } elsif ( $ISO ) {
    $defimage .= 'iso.tar';
  } else {
    $defimage .= $qin->param('image');
  }
  $defimage = $db->find_file("images/$defimage");
  unless ($defimage) { &end_it_now("Cannot find base image for $distro $version $arch!") }

# Copy over the image we will manipulate

  unless ( $ISO ) {
    print STDERR "Step2: Copying $defimage -> $custimg\n" if $debug;
    open(IN,"$defimage") ||
      &end_it_now("Cannot open defimage $defimage for reading : $!\n");
    open(OUT,">$custimg") ||
      &end_it_now("Cannot open custimage $custimg for writing : $!\n");
    while(<IN>) { print OUT };
    close(IN); close(OUT);
    unless ( -f "$custimg" ) { &end_it_now("Copy of image failed?!?!") }
  }

  my $sys;
  if ( $ISO ) {
    $sys = "/bin/tar -C $imgmount -xf $defimage";
  } else {
    $sys = "$SUDO /bin/mount -o loop,user,uid=$uid,rw -t msdos $custimg $imgmount";
  }
  &my_sys("$sys");
  $mounted = 1;
  unless (( -f "$custimg" ) || ( $ISO )) {
    &end_it_now("$custimg is not there?!?!?!");
  }
  $qout->message("Inserting YaST Info into boot image.");
  $qout->updatehtml(1);


  my $realdir;
  if ( $ISO ) {
    $realdir = "$imgmount";
  } else {
    $realdir = $imgmount;
  }

# Put the info file in initrd.img
  
# NOTE: you need SUDO perms for 'chmod', so we can write to the initrd minix
# visudo (as root)
#    webuid  hostname.atl.hp.com=NOPASSWD: /bin/chmod ?*
# if sudo is a prob, then just modify the original boot floppies i suppose.

# copy out initrd.img, decompress it, /bin/mount it, copy in YaST Info
  if ( $db->is_filesys_initrd($distro,$version,$arch) ) {
    &my_sys("/bin/cp $realdir/initrd $htmlpath/initrd.img$$.gz");
# BUG?  for some reason gunzip whines about SLES 8's initrd.  ignore return
#  &my_sys("$GUNZIP -q $htmlpath/initrd.img$$.gz");
    $sys = "$GUNZIP -q $htmlpath/initrd.img$$.gz";
    system $sys;
    unless ( -f "$htmlpath/initrd.img$$" ) {
      &end_it_now("$sys failed : $!\n");
    }
    mkdir("$initrdmount",0766) ||
      &end_it_now("Cannot mkdir $initrdmount : $!\n");
    $sys = "$SUDO /bin/mount -o loop,user,rw -t minix $htmlpath/initrd.img$$ $initrdmount";
    &my_sys("$sys");
    $sys = "$SUDO /bin/chmod 777 $initrdmount";
    &my_sys("$sys");
    if ( -f "$realdir/info" ) {
      &my_sys("$SUDO /bin/chmod 666 $realdir/info");
    }
    $sys = "/bin/cp $info_file $initrdmount/info";
    &my_sys("$sys");
# BUG: Temp workaround for OpenSuSE 10.3 - perhaps revert to all this way?
# https://bugzilla.novell.com/show_bug.cgi?id=333835
    $sys = "/bin/cp $info_file $initrdmount/info.txt";
    &my_sys("$sys");
    $sys = "/bin/cp $ks_file $initrdmount/autoyast.xml";
    &my_sys("$sys");
# Put a courtesy copy of autoyast.xml on root of iso
    system "/bin/cp $ks_file $realdir";
    &create_replay("$initrdmount/replay");
# unmount the initial ramdisk, lose mountpoint
    &my_sys( "$SUDO /bin/umount $initrdmount");
# compress the modified ramdisk image, and poke it back into the boot floppy
    &my_sys("$GZIP -c $htmlpath/initrd.img$$ >$realdir/initrd");

  } else {

    my $initrd = 'initrd';
    if ( $arch eq 'ia64' ) { $initrd = 'initdisk.gz' }
    &my_sys("/bin/cp $realdir/$initrd $htmlpath/initrd.img$$.gz");
    &my_sys("$GUNZIP $htmlpath/initrd.img$$.gz");                               # Uncompress CPIO image
    mkdir("$initrdmount",0766) || &end_it_now("Cannot mkdir $initrdmount : $!\n");
    #&my_sys("cd $initrdmount; $CPIO -i <$htmlpath/initrd.img$$");               # Extract CPIO image
    system "cd $initrdmount; $CPIO -i <$htmlpath/initrd.img$$"; 	# RHEL calls an error here, ignore return :/
    &my_sys("/bin/cp $info_file $initrdmount/info");                                # Poke in info file
# BUG: Temp workaround for OpenSUSE 10.3
    &my_sys("/bin/cp $info_file $initrdmount/info.txt");                                # Poke in info file
    &my_sys("/bin/cp $ks_file $initrdmount/autoyast.xml");                          # Poke in autoyast.xml
    &create_replay("$initrdmount/replay");
    &my_sys("cd $initrdmount; $FIND . | $CPIO -H newc -o >$htmlpath/initrd.img$$");    # Create CPIO image back
    &my_sys("$GZIP -c $htmlpath/initrd.img$$ >$realdir/$initrd");            	# Compress it back
    &my_sys("/bin/rm -rf $initrdmount");                                            # What body?

  }  # filesys vs. cpio initrd.img
  rmdir $initrdmount;

# If ia64, do what we gotta and return, otherwise fall thru to x86 code

  if ( $arch eq 'ia64' ) {

# Loopmount boot.img for elilo manipulation - let's reuse initrdmount
    mkdir("$initrdmount",0766) || &end_it_now("Cannot mkdir $initrdmount : $!\n");
    &my_sys("/bin/cp $info_file $initrdmount/info");                                # Poke in info file
    &my_sys("/bin/cp $ks_file $initrdmount/autoyast.xml");                          # Poke in autoyast.xml
    &my_sys("$SUDO /bin/mount -o loop,user,uid=$uid,rw -t vfat $realdir/image $initrdmount"); 
    my $elilo = $db->find_file("boot/elilo.conf-$distro-$version"); 			# Find elilo.conf
    unless($elilo) { $elilo = $db->find_file("boot/elilo.conf-$distro") }
    unless($elilo) { $elilo = $db->find_file("boot/elilo.conf") }
    unless($elilo) { &end_it_now("Cannot locate elilo.conf for $distro-$version") }
    &my_sys("/bin/cp $elilo $initrdmount/efi/boot/elilo.conf");				# Poke it in there
    $db->boot_lipstick("$initrdmount/efi/boot",$distro,$version,$arch,$waystation,$method,$profile,$ip,$nm,$gw,$ns,$final_text,$parts,$msgtail,$interface,$hostname,$kbd,$mouse,$lang,$timezone,\@bundles,\@coe_bundles,$defs);
    &my_sys("$SUDO /bin/umount $initrdmount");
    &my_sys("/bin/cp $info_file $imgmount/info");                                # Poke in info file
    &my_sys("/bin/cp $ks_file $imgmount/autoyast.xml");                          # Poke in autoyast.xml
    &my_sys("$MKISOFS -o $custimg -b image -c boot.catalog -no-emul-boot -J -r -T -pad $imgmount");
    &my_sys("/bin/rm -rf $imgmount");
    return;
  }

# Tweak image with SysDes boottime feel

  my $msgdir = $realdir;

  unless ( $ISO ) {

    $msgdir = "$htmlpath/bootnet.$$.dir";
    my $defimage .= "$distro-${version}-$arch-bootnet.img";
    $defimage = $db->find_file("images/$defimage");
    unless ($defimage) { &end_it_now("Cannot find base image for $distro $version $arch!") }
    &my_sys("mkdir $msgdir");
    &my_sys("/bin/cp $defimage $htmlpath/bootnet.$$");
    &my_sys("$SUDO /bin/mount -o loop,user,uid=$uid,rw -t msdos $htmlpath/bootnet.$$ $msgdir");

  }
 
# If we have a syslinux.cfg, jam it in:

  print STDERR "Inserting custom syslinux.cfg and boot.msg file onto floppy\n" if $debug;
  if ( $ISO ) {
    my $infile =  $db->find_file("boot/syslinux.yast-$distro-$version-$arch");
    unless ($infile) { $infile =  $db->find_file("boot/syslinux.yast-$distro-$version") }
    unless ($infile) { $infile =  $db->find_file("boot/syslinux.yast-$distro") }
    unless ($infile) { $infile =  $db->find_file("boot/syslinux.yast") }
    unless ($infile) {
      &end_it_now("Cannot locate boot/syslinux.yast, probable System Designer configuration error!");
    }
    &my_sys("/bin/cp -f $infile $realdir/isolinux.cfg");
  } else {
    my $infile =  $db->find_file("boot/syslinux.img.yast-$distro-$version-$arch");
    unless ($infile) { $infile =  $db->find_file("boot/syslinux.img.yast-$distro-$version") }
    unless ($infile) { $infile =  $db->find_file("boot/syslinux.img.yast-$distro") }
    unless ($infile) { $infile =  $db->find_file("boot/syslinux.img.yast") }
    unless ($infile) {
      &end_it_now("Cannot locate boot/syslinux.img.yast, probable System Designer configuration error!");
    }
    &my_sys("/bin/cp -f $infile $msgdir/syslinux.cfg");
  }


# Insert boot time env

   $db->boot_lipstick($realdir,$distro,$version,$arch,$waystation,$method,$profile,$ip,$nm,$gw,$ns,$final_text,$parts,$msgtail,$interface,$hostname,$kbd,$mouse,$lang,$timezone,\@bundles,\@coe_bundles,$defs) if ($ISO);
   $db->boot_lipstick($msgdir,$distro,$version,$arch,$waystation,$method,$profile,$ip,$nm,$gw,$ns,$final_text,$parts,$msgtail,$interface,$hostname,$kbd,$mouse,$lang,$timezone,\@bundles,\@coe_bundles,$defs) unless ($ISO);


# Run mkisofs if ISO
  if ( $ISO ) {
    &my_sys("$MKISOFS -o $custimg -b isolinux.bin -c boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -r -publisher \"LinuxCOE / Hewlett Packard / http://linuxcoe.sourceforge.net\" -A \"LinuxCOE Boot Image\" -p LinuxCOE -J -V LinuxCOE -T $imgmount");
  } else {
    &my_sys( "$SUDO /bin/umount $msgdir");
    rmdir("$htmlpath/bootnet.$$");
  } 

# If SIM is in play, make a tarball

  if ( $db->def('SIM') ) {
    my $simdir = $db->def('SIM');
    unless ( -d "$simdir/$serial") { mkdir "$simdir/$serial",0755 }
    $sys = "cd $imgmount && $TAR -cf $simdir/$serial/boot.tar *";
    &my_sys($sys);
  }


# Umount the image lookback & erase loopback dir

  &my_sys("$SUDO /bin/umount $imgmount") unless ($ISO);
  &my_sys("/bin/rm -rf $imgmount");

} # End of Step2 - loopback filesys is mounted

sub Init {

# Kick off the interactive HTML stuff

  $htmlfile = "/-/id$$.html";
  my $iesux = 0;
  if (( $ENV{HTTP_USER_AGENT} =~ /MSIE/ ) || ( $ENV{HTTP_USER_AGENT} =~ /Konq/ )) {
    $qout->htmlfile("$htmlfile");
    $iesux = 1;
  }
  $htmlfile = "$htmlpath/id$$.html";
  $qout->title("Linux Install Image Creation");
  $qout->persist("Linux Install Image Creation - working<blink>.</blink>");
  $qout->message("Initalizing");
  $qout->kickstart();            

} # End if Init


sub check_pass {

# Validate root passwd, KISS here, non-null and the same

  my @passwd = $qin->param('Root_Pass');
  if ((! $passwd[0] ) || (! $passwd[1] )) {
    &end_it_now("You must enter a root password, and do it twice!");
  }
  unless ( $passwd[0] eq $passwd[1] ) {
    &end_it_now("Sorry, your two root passwords don't match!");
  }           
  my $upass;
  my @upass = $qin->param('User_Pass');
  if (( $qin->param('User_Name')) && ($upass[0] ne $upass[1] )) {
     &end_it_now("Sorry, your two mortal user passwords don't match!");
  } else {
    $upass = $upass[0];
  }
  return($passwd[0],$upass);

}

sub end_it_now {

# Exit with extreme predjudice

  if ( $mounted ) {
    system "$SUDO /bin/umount $imgmount";
  }
  if ( -f $custimg ) { unlink $custimg }
  if ( -f $ks_filename ) { unlink $ks_filename }
  my $errmsg = shift(@_);
  my $admin = $db->def('SITE_ADMIN');
  $errmsg .= "<hr>If this error message looks bogus, contact <a href=\"mailto:$admin\">$admin</a>\n" if $admin;
  if ($replay) {
    print "START_OF_LINUXCOE_BEAM_DATA\nERR: $errmsg\nEND_OF_LINUXCOE_BEAM_DATA\n";
  }
  my $yikes = $db->err_msg;
  if ( $db->def('FINAL_INTERACTIVE') ) {
    $qout->persist("$yikes A catastrophic error!");
    $qout->message("$errmsg");
    $qout->updatehtml(0);
  } else {
    print $qin->header;
    $db->ShowNav("$yikes A catastrophic error!");
    print "<h2>$yikes A catastrophic error!</h2>\n";
    print $errmsg;
    print $qin->end_html;
    $db->ShowFooter;
  }
  exit;

}    

sub my_sys {

  my $sys = shift;
  system $sys;
  print STDERR "$sys\n" if $debug;
  if ($?) {
    &end_it_now("$sys returned $!");
  }

}

sub Add_COE_Hooks {

# Add LinuxCOE Bundles

     print KS qq[system "/bin/mkdir -p /etc/opt/LinuxCOE/apt.sources";\n];
     print KS qq[system "/bin/mkdir -p /etc/opt/LinuxCOE/yum.sources";\n];
     print KS qq[system "/bin/mkdir -p /etc/opt/LinuxCOE/sw";\n];
     print KS qq[open(PATCH,">/etc/opt/LinuxCOE/patch_method");
print PATCH "$patch_method\n";
close(PATCH);
];

# Do they want patches??  If so, touch PATCH_ME
    if ( $patch_me ) {
      print KS qq[ open(PATCH,">/etc/opt/LinuxCOE/sw/PATCH_ME");\n];
      print KS qq[close(PATCH);\n];
    }
# Do they want continued patching?
    if (( $patch_freq ) && ( $patch_freq ne 'never' )) {
      print KS qq[open(OUT,">/etc/cron.${patch_freq}/apt_patch");
      print OUT qq{#!/bin/bash
/bin/touch /etc/opt/LinuxCOE/sw/PATCH_ME
/etc/rc.d/init.d/LinuxCOE-Bundles start
};
system "/bin/chmod +x /etc/cron.${patch_freq}/apt_patch";\n ];
    }
                                                                                                                     
# This used to be done by %final, now drop bundle files in place and call installer

# Let's drop a little file wiht the tuple we were installed with
#
   print KS qq[open(OUT,">/etc/opt/LinuxCOE/INSTALLED");\n];
   print KS "print OUT qq[$distro $version $arch];\n";
   print KS "close(OUT);\n";

# Populate /etc/opt/LinuxCOE/apt.sources with what we'll need

# First do the base (OS and Patch Trees)

    my $t = $method;
    if (($t eq 'CDROM' ) || ($t eq 'NFS' )) {
       $t = $db->def('METHOD') || "HTTP";
    }
    $t = lc($t) . '://';
    my $infile = $db->find_file("depots/apt-$distro-$version-$arch");
    unless ($infile) { $infile = $db->find_file("depots/apt-$distro-$version") }
    unless ($infile) { $infile = $db->find_file("depots/apt-$distro") }
    if (open(SOURCES,"$infile")) {
      print KS qq[open(OUT,">/etc/opt/LinuxCOE/apt.sources/COE_BASE");\n];
      print KS "print OUT qq[";
      my $lines;
      while($lines = <SOURCES>) {
        $lines =~ s/\@METHOD\@/$t/g;
        $lines =~ s/\@WAYSTATION\@/$waystation/g;
        $lines =~ s/\@ARCH\@/$arch/g;
        $lines =~ s/\@DISTRO\@/$distro/g;
        $lines =~ s/\@VERSION\@/$version/g;
        print KS "$lines";
      }
      close(SOURCES);
      print KS "];\nclose(OUT);\n";
    }
    $infile = $db->find_file("depots/yum-$distro-$version-$arch");
    unless ($infile) { $infile = $db->find_file("depots/yum-$distro-$version") }
    unless ($infile) { $infile = $db->find_file("depots/yum-$distro") }
    if ( open(SOURCES,"$infile") ) {
      print KS qq[open(OUT,">/etc/opt/LinuxCOE/yum.sources/COE_BASE");\n];
      print KS "print OUT qq[";
      my $lines;
      while($lines = <SOURCES>) {
        $lines =~ s/\@METHOD\@/$t/g;
        $lines =~ s/\@WAYSTATION\@/$waystation/g;
        $lines =~ s/\@ARCH\@/$arch/g;
        $lines =~ s/\@DISTRO\@/$distro/g;
        $lines =~ s/\@VERSION\@/$version/g;
        print KS "$lines";
      }
      close(SOURCES);
      print KS "];\nclose(OUT);\n";
    }

# Now do add on depots

    my @NAMES = split(' ',$db->def('ADDONS'));
    foreach my $addon (@NAMES) {
      my ($config,$helpurl,$rpmapt,$debapt,$rpmyum,@needs) = $db->parse_addon_config($addon,$distro,$version,$arch);
      my ($d,$f,$count) = $db->parse_coe_bundles($arch,$distro,$version,$config);
      print STDERR "Addon $addon has $count entries for $distro $version $arch.\n" if $debug;
      next unless ($count);
      if ( $APT ) {
        $rpmapt =~ s/\@METHOD\@/$t/g;
        $rpmapt =~ s/\@WAYSTATION\@/$waystation/g;
        $rpmapt =~ s/\@ARCH\@/$arch/g;
        $rpmapt =~ s/\@DISTRO\@/$distro/g;
        $rpmapt =~ s/\@VERSION\@/$version/g;
        #$rpmapt =~ s/\@VERSION\@/SLES9/g;
        print KS qq[open(OUT,">/etc/opt/LinuxCOE/apt.sources/$addon");
print OUT "$rpmapt";
close(OUT);
];
      }
      if ( $YUM ) {
        $rpmyum =~ s/\@METHOD\@/$t/g;
        $rpmyum =~ s/\@WAYSTATION\@/$waystation/g;
        $rpmyum =~ s/\@ARCH\@/$arch/g;
        $rpmyum =~ s/\@DISTRO\@/$distro/g;
        $rpmyum =~ s/\@VERSION\@/$version/g;
        print KS qq[open(OUT,">/etc/opt/LinuxCOE/yum.sources/$addon");
print OUT "$rpmyum";
close(OUT);
];
      }

    }

    my ($d,$f) = $db->parse_coe_bundles($arch, $distro, $version, 'ALL');
    foreach my $bundle (@coe_bundles) {
      print STDERR "coe_bundle_roller: I have bundle $bundle!\n" if $debug;
      print STDERR "coe_bundle_roller:   files: ${$f}{$bundle}!\n" if $debug;
      my @files = split(' ',${$f}{$bundle});
      my $archin = shift(@files);
      my $rpms = join(' ',@files);
      $bundle_error = 1 unless ($rpms);
      my $name = $bundle;
      $bundle =~ tr/a-zA-z0-9/_/cs;
      print KS qq[open(OUT,">/etc/opt/LinuxCOE/sw/$bundle");
print OUT "$name\\n$rpms\\n";
close(OUT);
];

    }

    my $skel = $db->find_file("data/suse_final_skel");
    open(SKEL,"$skel") || &end_it_now("Error opening $skel : $!\n");

    while(<SKEL>) {
       # Stick in top of file
       last if /^# REAL_DATA_HERE/;
       next if /^#/;  # drop comments
       next if ( $_ eq "\n" ); # drop MT lines
       print KS;
    }
    print KS qq['WaYsTaTiOn' => "$wayip",\n];
    my %extra_rpms = $db->make_Base($method,$wayip,$distro,$version,$arch);
    foreach my $key (sort(keys(%extra_rpms))) {
      next unless ( $extra_rpms{$key} );
      print KS qq["$key" => "$extra_rpms{$key}",\n];
    }
    while(<SKEL>) {
       next if /^#/;  # drop comments
       next if ( $_ eq "\n" ); # drop MT lines
       print KS;
    }
    close(SKEL);

}

sub create_replay {

# Create a file with all the args we were called with, pick it up later on client

    my $replay_file = shift(@_);
    foreach my $parm ($qin->param) {
      $qin->delete($parm) if ( $parm =~ /Pass/i );  # Skip plaintext passwords :)
    }
    if (open(PARMOUT,">$replay_file")) {
      $qin->save(\*PARMOUT);
      close(PARMOUT);
    } else {
      print STDERR "Cannot open PARMOUT ($replay_file) : $!\n";
    }

}
__END__

sub Reality_Check {

# It's an express, make sure things are kosher....
#  Make sure it's vended...
  my $os = $qin->param('os');
  my $waystation = $qin->param('waystation');
  my $method = $qin->param('method');
  my ($dist,$ver) = split(' ',$os);
  if ( defined $dbh ) {
    my $qdist = $dbh->quote($dist);
    my $qver = $dbh->quote($ver);
    my $qmeth = $dbh->quote($method);
    my $qway = $dbh->quote($waystation);
    my $sql = "select path from osvend where distro = $qdist and version = $qver and method = $qmeth ";
    $sql .= "and hostname = $qway";
    my $sth = $dbh->prepare($sql);
    $sth->execute;
    my $count = $sth->rows;
    $sth->finish;
    unless ($count) {
      my $msg = "<P>Sorry, $os is not vended from $waystation using $method!</P>";
      $msg .= "Please try again!";
      &end_it_now($msg);
    }
  }
}
