# -*- perl -*-
# $Id: make-host-list.pl,v 1.2 1995/11/30 11:44:10 dm Exp $

# Much of this code is from make-ssh-known-hosts, by Tero Kivinen.
# See make-ssh-known-hosts (which comes with ssh) for the copying
# conditions.

require "getopts.pl";

$prog = $0;
$prog =~ s!.*/!!;

sub usage {
    print STDERR "usage: $prog [-d] domain [name-server]\n";
    print STDERR "   -d  inhibit stripping of domain name\n";
    exit 1;
}

$opt_d = 0;
&Getopts ('d') || &usage;

if (@ARGV < 1 || @ARGV > 2) {
    &usage;
}

$debug = 0;
($domain, $server) = @ARGV;

######################################################################
# finding SOA entry for domain

if (!defined($server)) {
    &debug(6, "Finding DNS database SOA entry");
    open(DNS, "nslookup -type=soa $domain 2>&1 |") ||
        die "Error: Could not start nslookup to find SOA entry for $domain : $!\
nError: Try giving the path to it with --nslookup option\n";
    
    while (<DNS>) {
        if (/\s+(\S+)\s*=\s*(.*)\s*$/) {
            $field = $1;
            $data = $2;
            &debug(10, "Found field $field = $data");
            if ($field =~ /origin/i) {
                $server = $data;
            }
        }
    }
    close(DNS);

    if (!defined($server)) {
        print(STDERR "Error: Could not find DNS SOA entry from default dns serve
r\nError: Try giving the initial nameserver with --initialdns option\n");
        exit(1);
    } else {
        &debug(5, "DNS server found : $server");
    }
} else {
    &debug(5, "Using given DNS server : $server");
}


######################################################################
# Get DNS database list from server

&debug(0, "Getting DNS database from server $server");
open(DNS, "echo ls -d $domain | nslookup - $server 2>&1 |") ||
    die "Error: Could not start nslookup to make dns list : $!\nError: Try giving --nslookup option and telling the path to nslookup program\n";

$hostcnt = 0;
$cnamecnt = 0;
$lines = 0;
while(<DNS>) {
    $lines++;
    if (/^\s+(\S+)\s+(\S+)\s+(.*)\s*$/) {
	$host = "\L$1\E";
	$field = "\L$2\E";
	$data = "\L$3\E";
	&debug(50, "Line = /$host/$field/$data/");
	if ($host !~ /\.$/) {
	    $host .= ".$domain";
	} else {
	    $host =~ s/\.$//g;
	}
	if ($field eq "a") {
	    if ($host =~ /$domain$/) {
		if (defined($host{$host})) {
		    $host{$host} .= ",$data";
		} else {
		    $host{$host} = "$data";
		    $hostcnt++;
		}
		&debug(30, "$host A == $host{$host}");
	    }
	} elsif ($field eq "cname") {
	    if ($host =~ /$domain$/) {
		if (defined($cname{$data})) {
		    $cname{$data} .= ",$host";
		} else {
		    $cname{$data} = "$host";
		    $cnamecnt++;
		}
		&debug(30, "$host CNAME $data");
	    }
	}
	if (!defined($hostdata{$host})) {
	    $hostdata{$host} = "$host\n$field=$data\n";
	} else {
	    $hostdata{$host} .= "$field=$data\n";
	}
    }
}
close(DNS);
&debug(0, "Found $hostcnt hosts, $cnamecnt CNAMEs (total $lines lines)");

sub debug {
    local($level, $str) = @_;
    if ($debug > $level) {
	print(STDERR "$0:debug[$level]: $str\n");
    }
}

sub inua {
    local ($h) = @_;
    local ($ret) = !defined ($ua{$h});
    $ua{$h} = 1;
    $ret;
}

foreach $host (keys %host) {
    local ($namelist,$cnames, %ua);
    next unless $host =~ /.*$domain\.?$/;
    next if $host =~ /^localhost\./;
    $addr = $addrlist = $host{$host};
    $addr =~ s/,.*//;
    $addrlist = join (',', grep (&inua ($host), split (/,/, $addrlist)));
    $cnames = defined ($cname{$host}) ? "," . $cname{$host} : "";
    $namelist = "";
    unless ($opt_d) {
	foreach $name ($host, split (/,/, $cnames)) {
	    if ($name =~ /^(.*)\.$domain\.?$/) {
		$namelist .= ",$1";
	    }
	}
    }
    print "$addr $host$cnames$namelist,$addrlist\n";
}
