#!/usr/bin/perl

open (STDERR, ">&STDOUT");
select ((select(STDOUT), $| = 1)[0]); # Synchronize STDOUT
select ((select(STDERR), $| = 1)[0]); # with STDERR

($dns_lib = $0) =~ s:(^|/)[^/]*$::;
($script=$0) =~ s:^.*/([^/]*)$:$1:;	# Get the simple name of this script.

push (@INC, $dns_lib);

require 5.0;
require 'dns_lib.perl';

# if ($ENV{'USER'} ne $user) {

#    die "This script can only be run by $user.\n";

# }

umask 0177;

use Getopt::Long;
$Getopt::Long::autoabbrev=1;    # Allow keyword abbreviations (to uniqueness).
$Getopt::Long::getopt_compat=1; # Allow both "--foo=bar" and "+foo=bar" style.
#$Getopt::Long::option_start='(--|-|\+)';       # [Use the defaults]
#$Getopt::Long::order=$Getopt::Long::REQUIRE_ORDER; # Options can't intermingle
$Getopt::Long::order=$Getopt::Long::PERMUTE;    # or options may intermingle.
$Getopt::Long::ignorecase=1;    # Don't consider case in options.
$Getopt::Long::debug=0;         ### Debug ###

&GetOptions ('help', 'rebuild', 'reboot', 'rmbak') || die "Try $script --help for more information.\n";

if (($opt_help) || ($#ARGV >= 0)) { 
 
    print <<"EndOfHelp";
Usage: $script [OPTION]
 
  --help      This info
  --reboot    Force the restart of named on all servers
  --rebuild   Force the rebuild of named.boot files (must also
              restart  --reboot)
  --rmbak     Force the removal of all .bak files on secondary
              servers if rebooting (--reboot)
 
EndOfHelp
    
    exit;

} # End if - help

$ftp_flag = 0;

print "\nStarting DNS Rebuild...\n\n";

print "Building database files for BIND...\n";
$status = system "$build_db";
die "DB Rebuild Failed: $!\n" if $status;
print "Done.\n\n";

if (-e "$tree_root/.rmzones") {

    $opt_reboot = 1;

}

if (-e "$tree_root/.rebuild") {

    $opt_rebuild = 1;
    $opt_reboot = 1;

}

if (defined ($opt_reboot)) {
    
    open (REBOOT, ">$tree_root/.reboot") || die "Cannot open .reboot: $!\n";
    print "Building .reboot script...\n";

    if (defined ($opt_rmbak)) {

	print REBOOT "/bin/rm -f $bind_bak_files/*.bak*\n";

    } elsif (-e "$tree_root/.rmzones") {
	    
	open (RMZONES, "$tree_root/.rmzones") || die "Cannot open .rmzones: $!\n";
	
	while (<RMZONES>) {

	    # print "Adding $_\n";
	    print REBOOT "/bin/rm -f $bind_bak_files/$_";

	}

	close RMZONES;

    }

    print REBOOT '/usr/sbin/named.restart';
    close REBOOT;

    print "Done.\n\n";

    open (NETRC, ">$dns_home/.netrc") || die "Cannot create $dns_home/.netrc: $!\n";

    foreach $server (sort (keys (%downstream))) {

	if ($server eq $master_server) {

	    print NETRC "machine $server\n";
	    print NETRC "login $downstream{$server}->{'user'}\n";
	    print NETRC "password $downstream{$server}->{'pass'}\n";
	    print NETRC "macdef init\n";
	    print NETRC "cd $dns_logs\n";
	    print NETRC "put $tree_root/.reboot .reboot\n";
	    print NETRC "bye\n";
	    print NETRC "\n";

	}

    }

    close NETRC;
    
    print "FTPing .reboot script...\n\n";

    foreach $server (sort (keys (%downstream))) {

	if ($server eq $master_server) {

	    $status = system $ftp, $server;

	}

    }

    unlink "$dns_home/.netrc";
    print "Done.\n\n";

}

if (defined ($opt_rebuild)) {

    print "Checking named.boot files...\n";

    foreach $server (sort (keys (%downstream))) {

	$dot = '';
	$named = '';
	$named .= 'nosec.' if $downstream{$server}->{'nosec'};

	if ($downstream{$server}->{'data_from'} ne '') {

	    $named .= "$downstream{$downstream{$server}->{'data_from'}}->{'ip'}";
	    $dot = '.';

	}

	foreach $class (sort (@{$downstream{$server}->{'classes'}})) {

	    $named .= "$dot$class";
	    $dot = '.';
		
	}

	$downstream{$server}->{'named_boot'} = "named.boot.$named";
	$named_files{$named} = 1;

    }

    foreach (sort (keys (%named_files))) {

	$command_args = '';

	if (s/^nosec\.//) {

	    $command_args .= " --nosec";

	}

	if (m/master$/) {

	    $command_args .= " --master";

	} else {

	    s/^(\d+\.\d+\.\d+\.\d+)\.?//;
	    $source = $1;
	    $command_args .= " --source=$source";
	    split (/\./);
	    foreach (@_) {

		$command_args .= " --class=$_";

	    }

	}

	# print "$build_named_boot$command_args\n";
	$status = system "$build_named_boot$command_args";
	die "$build_named_boot $command_args failed: $!\n" if $status;

    }
	
    print "Done.\n\n";

    foreach $server (sort (keys (%downstream))) {

	open (NETRC, ">$dns_home/.netrc") || die "Cannot create $dns_home/.netrc: $!\n";

	print NETRC "machine $server\n";
	print NETRC "login $downstream{$server}->{'user'}\n";
	print NETRC "password $downstream{$server}->{'pass'}\n";
	print NETRC "macdef init\n";

	if (defined ($opt_rebuild)) {

	    print NETRC "cd /etc\n";
	    print NETRC "put $tree_root/.bootfiles/$downstream{$server}->{'named_boot'} named.boot\n";

	}

	print NETRC "bye\n";
	print NETRC "\n";
	close NETRC;
    
	print "\nFTPing named.boot file to $server...\n";

	$status = system $ftp, $server;
	unlink "$dns_home/.netrc";
	print "Done.\n";

    }

}

if ($opt_reboot) {

    print "\nYou can just wait for cron to restart named or on the master server as root:\n\n";
    print "\t> local.named.restart\n";

}

unlink "$tree_root/.rmzones";
unlink "$tree_root/.rebuild";
unlink "$tree_root/.reboot";

print "\n";
    
exit;
