#!/usr/bin/perl -w

#
# "SystemImager" - Copyright (C) 1999-2001 Brian Elliott Finley <brian@systemimager.org>
#
#   Others who have contributed to this code (in alphabetical order):
#     John Goebel <jgoebel@valinux.com>
#     Curtis Zinzilieta <czinzilieta@valinux.com>
#
# This file is: mkdhcpserver
#
 

# what do I call myself?
$program=$0;

# Not everyone may want to create a dhcpd.conf in /etc...
$dhcpd_conf = "/etc/dhcpd.conf";

### BEGIN variable for parts of the dhcpd.conf file ###
# associated configs for the dhcpd.conf file
$dhcpd_conf_v3_part1 = <<"EOF";

# general options
ddns-update-style none;
host-checking true;

EOF


$dhcpd_conf_v3_part2 = <<"EOF";

# make network booting the SystemImager autoinstallclient possible
allow booting;
allow bootp;

# set lease time to 3 days
default-lease-time 259200;
max-lease-time 259200;

# what to get to boot the autoinstallclient
filename "/pxelinux.bin";
option vendor-class-identifier "PXEClient";
option vendor-encapsulated-options 09:0f:80:00:0c:4e:65:74:77:6f:72:6b:20:62:6f:6f:74:0a:07:00:50:72:6f:6d:70:74:06:01:02:08:03:80:00:00:47:04:80:00:00:00:ff;

EOF


$dhcpd_conf_v2_part1 = <<"EOF";

# make network booting the SystemImager autoinstallclient possible
allow booting;
allow bootp;

# set lease time to 3 days
default-lease-time 259200;
max-lease-time 259200;

# what to get to boot the autoinstallclient
filename "/pxelinux.bin";
option dhcp-class-identifier "PXEClient";
option vendor-encapsulated-options 09:0f:80:00:0c:4e:65:74:77:6f:72:6b:20:62:6f:6f:74:0a:07:00:50:72:6f:6d:70:74:06:01:02:08:03:80:00:00:47:04:80:00:00:00:ff;

EOF

### END variables for parts of dhcpd.conf file ###



# Subroutines
sub get_response {
 my $garbage_out=$_[0];
 my $garbage_in=<STDIN>;
 chomp $garbage_in;
 unless($garbage_in eq "") { $garbage_out = $garbage_in; }
 return $garbage_out;
}

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

system("clear");

# give warning
print <<"EOF";

Welcome to the SystemImager "mkdhcpserver" command.  This command
will prepare this computer to be a DHCP server by creating the 
following file:

 $dhcpd_conf

If there is an existing file, it will be backed up as:

 ${dhcpd_conf}.beforesystemimager

EOF

print "Continue? (y/[n]): ";
$continue=<STDIN>;
chomp $continue;
($continue eq "y") or die "\n$program: No files were modified.\n";

# backup dhcpd.conf if necessary
if( -e "$dhcpd_conf" && ! -e "${dhcpd_conf}.beforesystemimager") { 
 rename("$dhcpd_conf", "${dhcpd_conf}.beforesystemimager");
}

# set some default values
$dnsdomainname="localdomain.domain";
$netnumber = "192.168.1.0";
$netmask = "255.255.255.0";
$rangebegin = "192.168.1.1";
$rangeend = "192.168.1.100";
$dnsserver1 = "";
$dnsserver2 = "";
$dnsserver3 = "";
$router = "192.168.1.254";
$imageserver = "192.168.1.254";
$ssh_download_url = "";
$swallow = "";

### Begin questionnaire ###
$satisfied = "n";
while ($satisfied ne "y") {
 system("clear");
 print << "EOF";
Type your response or hit <Enter> to accept [defaults].  If you don't
have a response, such as no first or second DNS server, just hit 
<Enter> and none will be used.

EOF

 print "\nWhat is your domain name? [$dnsdomainname]: ";
 $dnsdomainname=get_response($dnsdomainname);

 print "What is your network number? [$netnumber]: ";
 $netnumber=get_response($netnumber);

 print "What is your netmask? [$netmask]: ";
 $netmask=get_response($netmask);

 print "What is the starting IP address for your dhcp range? [$rangebegin]: ";
 $rangebegin=get_response($rangebegin);

 print "What is the ending IP address for your dhcp range? [$rangeend]: ";
 $rangeend=get_response($rangeend);

 print "What is the IP address of your first DNS server? [$dnsserver1]: ";
 $dnsserver1=get_response($dnsserver1);

 if ($dnsserver1) {
   print "What is the IP address of your second DNS server? [$dnsserver2]: ";
   $dnsserver2=get_response($dnsserver2);
 }

 if ($dnsserver2) {
   print "What is the IP address of your third DNS server? [$dnsserver3]: ";
   $dnsserver3=get_response($dnsserver3);
 }

 print "What is the IP address of your default gateway? [$router]: ";
 $router=get_response($router);

 print "What is the IP address of imageserver? [$imageserver]: ";
 $imageserver=get_response($imageserver);

 print "\nWill your clients be installed over SSH? (y/[n]): ";
 my $ssh_install=<STDIN>;
 chomp $ssh_install;
 if ($ssh_install eq "y") {
   if ($ssh_download_url eq "") { $ssh_download_url="http://$imageserver/ssh_files/"; }
   print "What is the URL for your ssh_files directory? [$ssh_download_url]: ";
   $ssh_download_url=get_response($ssh_download_url);
 }

 # see http://www.armory.com/swallowscenes.html for details
 print "\nWhat... is the air-speed velocity of an unladen swallow? [$swallow]: ";
 $swallow=<STDIN>;
 system("clear");
 chomp $swallow;
 $swallow = lc $swallow;
 if($swallow =~ /african/) {
  print "Aaaaaaaaaaaaaaaaaaaaaaaaaaaah!\n";
 } else {
  print "Wrong!!! (with a Monty Python(TM) accent...)\n";
 }
 print "\nPress <Enter> to continue...";
 <STDIN>;

 system("clear");
 print "Ahh, but seriously folks...\n";
 print "Here are the values you have chosen:\n\n";
 print "#######################################################################\n";
 print "DNS domain name:                          $dnsdomainname\n";
 print "Network number:                           $netnumber\n";
 print "Netmask:                                  $netmask\n";
 print "Starting IP address for your DHCP range:  $rangebegin\n";
 print "Ending IP address for your DHCP range:    $rangeend\n";
 print "First DNS server:                         $dnsserver1\n";
 print "Second DNS server:                        $dnsserver2\n";
 print "Third DNS server:                         $dnsserver3\n";
 print "Default gateway:                          $router\n";
 print "ImageServer:                              $imageserver\n";
 print "SSH files download URL:                   $ssh_download_url\n";
 print "#######################################################################\n";
 
 print "\nAre you satisfied? (y/[n]): ";
 $satisfied=<STDIN>;
 chomp $satisfied;
}

### End questionnaire ###


# discover which version of dhcpd we're using, if possible
# assume that dhcpd is in the path
$rc = `dhcpd --version`;
$rc =~ m/dhcpd-V3/;
if ($&) { $dhcpd_version = 3; } else { $dhcpd_version = 2; }


# open /etc/dhcpd.conf for writing
open(DHCPDCONF, "> $dhcpd_conf") || die "Couldn't open /etc/dhcpd.conf for writing: $!\n";


# create a configuration file, depending on which version of dhcpd we found
if ($dhcpd_version eq "2") {
  # version 2, at least for now
  print DHCPDCONF $dhcpd_conf_v2_part1;

  print DHCPDCONF qq(subnet $netnumber netmask $netmask { \n);
  print DHCPDCONF qq(  range  $rangebegin $rangeend; \n);
  print DHCPDCONF qq(  option domain-name "$dnsdomainname"; \n);
  if($dnsserver1 ne "") { print DHCPDCONF qq(  option domain-name-servers $dnsserver1); }
  if($dnsserver2 ne "") { print DHCPDCONF qq(, $dnsserver2); }
  if($dnsserver3 ne "") { print DHCPDCONF qq(, $dnsserver3); }
  if($dnsserver1 ne "") { print DHCPDCONF qq(;\n); }
  print DHCPDCONF qq(  option routers $router; \n);
  print DHCPDCONF qq(  # option-100 specifies the IP address of your SystemImager image server\n);
  print DHCPDCONF qq(  option option-100 "$imageserver"; \n);
  print DHCPDCONF qq(  # option-208 specifies the URL address of your ssh download\n);
  if($ssh_download_url eq "") { print DHCPDCONF qq ( # ); }
  print DHCPDCONF qq(  option option-208 "$ssh_download_url"; \n);
  print DHCPDCONF qq( } \n);

} else {
  # version 3, at least for now
  print DHCPDCONF $dhcpd_conf_v3_part1;

  print DHCPDCONF qq(  # option-100 specifies the IP address of your SystemImager image server\n);
  print DHCPDCONF qq(  option option-100 code 207 = ip-address; \n);
  print DHCPDCONF qq(  option option-100 $imageserver; \n);
  print DHCPDCONF qq(  # option-208 specifies the URL address of your ssh download\n);
  if($ssh_download_url eq "") { print DHCPDCONF qq ( # ); }
  print DHCPDCONF qq(  option option-208 code 208 = string; \n);
  if($ssh_download_url eq "") { print DHCPDCONF qq ( # ); }
  print DHCPDCONF qq(  option option-208 "$ssh_download_url"; \n);

  print DHCPDCONF $dhcpd_conf_v3_part2;

  print DHCPDCONF qq(subnet $netnumber netmask $netmask { \n);
  print DHCPDCONF qq(  range  $rangebegin $rangeend; \n);
  print DHCPDCONF qq(  option domain-name "$dnsdomainname"; \n);
  if($dnsserver1 ne "") { print DHCPDCONF qq(  option domain-name-servers $dnsserver1); }
  if($dnsserver2 ne "") { print DHCPDCONF qq(, $dnsserver2); }
  if($dnsserver3 ne "") { print DHCPDCONF qq(, $dnsserver3); }
  if($dnsserver1 ne "") { print DHCPDCONF qq(;\n); }
  print DHCPDCONF qq(  option routers $router; \n);
  print DHCPDCONF qq( } \n);

}


# close and chmod the new dhcpd.conf file
close(DHCPDCONF);
system("chmod 600 $dhcpd_conf");


# Oh where oh where could my leases file directory be?
@lease_file_directories_du_jour = ( 
  "/var/dhcp",
  "/var/state/dhcp",
  "/etc"
);

foreach my $directory (@lease_file_directories_du_jour) {
    # does *this* one exist?
    if ( -d "$directory" ) { 
        $dhcpd_lease_file_directory = $directory;
    }
    last if ( $dhcpd_lease_file_directory );
}

# Touch dhcpd.leases file so that dhcpd won't fart when started.
# Different installs put the file in different places so we touch
# one of several potential files and a monkey.
if( -d "$dhcpd_lease_file_directory" )
{
     my $file="$dhcpd_lease_file_directory/dhcpd.leases";
     system("touch $file");
     ($?) && die "\n$program: Couldn't touch $file.\n";
}

# words of wisdom
system("clear");
print <<"EOF";

The dhcp server configuration file (/etc/dhcpd.conf) file has been 
created for you.  Please verify it for accuracy.

If this file does not look satisfactory, you can run this command again
to re-create it: "mkdhcpserver"

WARNING!:  If you have multiple physical network interfaces, be sure to 
edit the init script that starts dhcpd to specify the interface that 
is connected to your DHCP clients.  Here's an example:

 Change "/usr/sbin/dhcpd" to "/usr/sbin/dhcpd eth1".

Also, be sure to start or restart your dhcpd daemon.  This can usually
be done with a command like "/etc/init.d/dhcpd restart" or similar.

EOF

if( -e "/etc/rc.d/init.d/dhcpd" ){
  print "Would you like me to restart your DHCP server software now? (y/[n]): ";
  $continue=get_response();
  $continue=lc($continue);
  if( $continue eq "y" ){
    $command="/sbin/service dhcpd restart";
    system($command);
  }
}

exit 0;
