simple/dns/dns-inc-serial

71 lines
1.6 KiB
Perl
Executable File

#!/usr/bin/perl
use warnings;
use strict;
use Getopt::Long;
use Net::DNS::Resolver;
my $cfg;
GetOptions('config:s' => \$cfg);
my %file2zone;
my $res;
if ($cfg) {
# XXX - this is very simplistic
open(my $fh, '<', $cfg) or die "cannot open $cfg: $!";
my $currentzone;
while (<$fh>) {
if (/zone "(.*?)"/) {
$currentzone = $1;
} elsif (m{file ".*/(.*)"}) {
$file2zone{$1} = $currentzone;
}
}
$res = Net::DNS::Resolver->new();
}
for my $f (@ARGV) {
my $maxserial = 0;
if (my $zone = $file2zone{$f}) {
my $reply = $res->send($zone, 'NS');
my @nsnames;
for my $ans ($reply->answer) {
push @nsnames, $ans->nsdname;
}
my @nsips;
for (@nsnames) {
my $reply = $res->send($_, 'A');
for my $ans ($reply->answer) {
push @nsips, $ans->address if $ans->type eq 'A';
}
}
for (@nsips) {
$res->nameservers($_);
my $reply = $res->send($zone, 'SOA');
for my $ans ($reply->answer) {
if ($ans->type eq 'SOA') {
# XXX assume no wraparound
if ($ans->serial > $maxserial) {
$maxserial = $ans->serial;
}
}
}
}
}
open (my $in, '<', "$f") or die "cannot open $f: $!";
open (my $out, '>', "$f.new") or die "cannot open $f.new: $!";
while (<$in>) {
if (/(.*\bSOA\b.*?)(\d+)( \d+ \d+ \d+ \d+)/) {
my $serial = $2;
$maxserial = $serial if ($serial > $maxserial);
$maxserial++;
print $out "$1$maxserial$3\n";
} else {
print $out $_;
}
}
close($out) or die "cannot close $f.new: $!";
rename "$f.new", $f || die "cannot rename $f.new to $f: $!";
}