#!/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';

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=0;    # Do consider case in options.
$Getopt::Long::debug=0;         ### Debug ###

$opt_help = ($#ARGV < 0);

&GetOptions ('help', 'R') || die "\nTry: $script --help for more information.\n\n";

if ($opt_help) { 
 
    print <<"EndOfHelp";
Usage: $script [OPTION] zone
 
  --help   This page.
  --R      Recurse from starting zone.

  zone     The DNS zone to verify
 
EndOfHelp
    
    exit;

} # End if - help

$start_zone = $ARGV[0];

if (! $start_zone) {

    die "\nError.  Try: $script --help for more information.\n\n";

} else {

    $start_zone = &zone_or_subnet ($start_zone);
    $subnet = 1 if $check_zone =~ m/\.in-addr\.arpa\.?$/;
    
}

@dirs = ();
$start_path = &zone_to_path ($start_zone);
$start_path =~ s/\/$//;
push (@dirs, $start_path);

while ($current = pop (@dirs)) {

    $check_zone = &path_to_zone ($current);
    opendir (DIR, $current);
    @files = readdir (DIR);
    closedir (DIR);

    FILE_LOOP: foreach $file (reverse (sort (@files))) {

	next if $file eq 'RCS';
	next if $file =~ m/^\.\.?$/;

	if ((-d "$current/$file") && (defined ($opt_R))) {

	    push (@dirs, "$current/$file");

	} elsif ("$file" eq '.primary') {
	    
	    @ns_file = &read_file ($check_zone, '.primary');
	    print "Checking NS Records in $check_zone for needed glue records:\n";
	    print "\n";

	    NS_LOOP: foreach (@ns_file) {

		chomp;

		if (m/^(\S+)\s+IN\s+NS\s+(\S+)$/) {
	
		    $record = $1;
		    $name = $2;
		    ($host, $zone) = split ('\.', $name, 2);
	    
		    if ((($x = &verify_zone ($name)) eq 'PRIMARY') || ($x eq 'SEC_W_GLUE')) {
		
			$host = '@';
			$zone = $name;
		
		    } elsif ((($x = &verify_zone ($zone)) ne 'PRIMARY') && ($x ne 'SEC_W_GLUE')) {
			
			$possible = 0;
	    
			for ($soa = $zone;$soa =~ s/^[^\.]+\.//;) {

			    $path = &zone_to_path ($soa);

			    if (-e "$path/.soa") {

				print "NS Record: $record -- No glue (A Record) for $name\n";
				$possible = 1;
				last;

			    }

			}	    
	    
			print "NS Record: $record -- Not possible to have glue for $name\n" unless $possible;
			next NS_LOOP;
		
		    }
	    
		    @file = &read_file ($zone, '.primary');
		    @recs = &find_record (&build_record ($host, 'A', '', ''), @file);
		    
		    if ($#recs < 0) {
			
			print "NS Record: $record -- No glue (A Record) for $name\n";
			
		    }
		    
		}
		
	    }
	
	    print "Done.\n\n";
    
	}

    }

}

exit;

