Takes a BIND zone file & flattens any $INCLUDEs into a zone file stored elsewhere. I wrote this because we had many zones that were being transfered from a RAQ to a normal FreeBSD BIND server. The included files were almost always one line (the NS record), and just cluttering up a nice disk ;-).
Enjoy.
#!/usr/bin/perl
# flatdns.pl: flatten zone files that
# have $INCLUDE directives in them;
# This is a basic Unix filter: the source file
# is read until a $INCLUDE is met, the file
# is read & placed where the $INCLUDE was and
# the program continues on. Can do nested includes
# and doesn't touch the original files.
$|++;
use strict;
use Getopt::Std;
use Cwd;
my (%args,@files,$debug,$zoneinp,$zoneout,$line);
$debug = 0;
getopts('vi:o:h',\%args);
if(!defined $args{'i'} || !defined $args{'o'} || defined $args{'h'})
{
print <<EOU;
Usage:
flatdns.pl [options]
-i: input directory
-o: output directory
-v: Print debug/verbose info
-h: show this usage info
e.g.:
flatdns -i /etc/named/old-zones -o /etc/named/zones -v
YOU MUST SPECIFY AN INPUT & OUTPUT DIRECTORY!
EOU
}
$zoneinp = $args{'i'};
$zoneout = $args{'o'};
$debug = 1 if (defined $args{'v'});
@files = glob("$zoneinp/db.*.{com,biz,org,net}");
foreach(@files)
{
print "Processing $_\n" if $debug;
open(ZNEINP,'<',$_) or die "Cannot open \"$_\":$!\n";
$_ =~ s/\/.*\///;
open(ZNEOUT,'>',"$zoneout/$_") or die "Cannot create \"$_\":$!\n";
while($line = <ZNEINP>)
{
if($line =~ /^\$INCLUDE/)
{
procfile(*ZNEOUT,$line);
}
else
{
print ZNEOUT $line;
}
}
close(ZNEINP);
close(ZNEOUT);
}
sub procfile
{
my ($fh,$incline) = @_;
my ($tmp,@inc);
chomp($incline);
print "INC: $incline\n" if $debug;
@inc = split(/ /,$incline);
print "FILE: $inc[1]\n" if $debug;
print "CWD : ",getcwd,"\n" if $debug;
open(INCINP,'<',$zoneinp . "/" . $inc[1]) or die "Cannot open file
+ $inc[1]:$!\n";
while($tmp = <INCINP>)
{
if($tmp =~ /^\$INCLUDE/)
{
procfile($fh,$tmp);
}
else
{
print $fh $tmp;
}
}
close(INCINP);
}