#!/usr/bin/perl -w
#
# Sort bind zone file by IP number
#
# 2003-05-03 Dobrica Pavlinusic <dpavlin@rot13.org>
#
# parse files in format
#
# name A 111.222.333.444
# name CNAME name
#
# and output sorted list

use strict;

my %a_rec;
my %cname;

while(<>) {
	chomp;
	my ($name,$type,$ip) = split (/\s+/,$_,3);
	if (lc($type) eq "a") {
		if ($ip =~ /(\d+)\.(\d+)\.(\d+)\.(\d+)/) {

			my $i = ((((($1 * 255 + $2) * 255) + $3) * 255) + $4) * 100;
			while ($a_rec{$i}) { $i++; }
#print "$i: $name $type $ip\n";
			$a_rec{$i} = [ $name, $type ,$ip ];
		} else {
			print "; can't parse IP: $ip -- original line below:\n";
			print "; $name\t$type\t$ip\n";
		}
	} elsif (lc($type) eq "cname") {
		$cname{$ip} .= $name."\t";
	} else {
		print "; unknown type: $type -- original line below:\n";
		print "; $name\t$type\t$ip\n";
	}
}

print ";\n";
my $netmask_regex='^\d+\.\d+';		# bclass
my $net = "";

foreach my $key (sort(keys %a_rec)) {
	my ($name,$type,$ip) = @{$a_rec{$key}};

	if ($ip =~ /($netmask_regex)/) {
		if ($1 ne $net) {
			$net = $1;
			print ";\n; network $net\n;\n";
		}
	} else {
		print "; can't parse $ip to find network!\n";
	}

	# pretty format record
	sub dump_rec {
		my $name = shift @_;
		print "$name\t";
		print "\t" if (length $name < 8);
		print shift @_,"\t",shift @_,"\n";
	}

	# dump a
	dump_rec($name,$type,$ip);

	# dump cname if exists
	if ($cname{$a_rec{$key}[0]}) {
		foreach my $alias (split(/\t/,$cname{$a_rec{$key}[0]})) {
			undef $cname{$a_rec{$key}[0]};
			dump_rec($alias,"CNAME",$a_rec{$key}[0]);
		}
	}
}

print "; CNAME to CNAME\n";
foreach my $alias (keys %cname) {
	next if (! $cname{$alias});
	foreach my $host (split(/\t/,$cname{$alias})) {
		dump_rec($host,"CNAME",$alias);
	}
}
