--- a/vidns Thu May 22 16:17:32 2014 +0200
+++ b/vidns Thu May 22 16:17:47 2014 +0200
@@ -8,20 +8,20 @@
sub parse {
my $file = shift;
- my @lines = split /\n/, do {
- local $/ = undef;
- local @ARGV = $file;
- <>;
+ my @lines = split /\n/, do {
+ local $/ = undef;
+ local @ARGV = $file;
+ <>;
};
my @zone;
my ($origin, $ttl, $last_label, $soa_seen);
foreach (@lines) {
- s{;.*$}{};
+ s{;.*$}{};
given ($_) {
- when (m{^\s*\$ORIGIN\s+(\S+)}) { $origin = $1 }
- when (m{^\s*\$TTL\s+(\S+)}) { $ttl = $1 }
+ when (m{^\s*\$ORIGIN\s+(\S+)}) { $origin = $1 }
+ when (m{^\s*\$TTL\s+(\S+)}) { $ttl = $1 }
when (
m{^(?<label>\S+)?
\s+(?<ttl>\S+(?=\s+))?
@@ -30,47 +30,54 @@
}x
)
{
- my %rrset = (
- label => $last_label = defined $+{label}
- ? $+{label} eq '@' ? $origin : $+{label}
- : $last_label,
- ttl => h2ttl($+{ttl} // $ttl),
- rrtype => uc $+{rrtype},
- data => $+{data},
- );
+ my %rrset = (
+ label => $last_label =
+ defined $+{label}
+ ? $+{label} eq '@'
+ ? $origin
+ : $+{label}
+ : $last_label,
+ ttl => h2ttl($+{ttl} // $ttl),
+ rrtype => uc $+{rrtype},
+ data => $+{data},
+ );
- if ($rrset{rrtype} eq 'SOA') {
- next if $soa_seen;
- $soa_seen = 1;
- }
+ if ($rrset{rrtype} eq 'SOA') {
+ next if $soa_seen;
+ $soa_seen = 1;
+ }
-
+ # label ergänzen, wenn nicht FQDN
+ $rrset{label} .= ".$origin"
+ unless substr($rrset{label}, -1) eq '.';
- # label ergänzen, wenn nicht FQDN
- $rrset{label} .= ".$origin" unless substr($rrset{label}, -1) eq '.';
+ given ($rrset{rrtype}) {
+
+ # origin steht im SOA
+ when ('SOA') {
+ $origin = $rrset{label};
+
+ # fix the nameserver name
+ $rrset{data} =~ s{^(\S+[^.])(?=\s)}{$1.$origin};
- given ($rrset{rrtype}) {
- # origin steht im SOA
- when('SOA') {
- $origin = $rrset{label};
- # fix the nameserver name
- $rrset{data} =~ s{^(\S+[^.])(?=\s)}{$1.$origin};
- # fix the hostmaster address
- $rrset{data} =~ s{^\S+\s+\K(\S+[^.])(?=\s)}{$1.$origin};
- }
- # bei einigen RRs müssen wir die Daten korrigieren
- when ([qw/MX NS PTR/]) {
- $rrset{data} .= ".$origin" unless substr($rrset{data}, -1) eq '.';
- }
- }
- my $id = sha512_hex(sort %rrset);
- push @zone, {id => $id, rrset => \%rrset};
+ # fix the hostmaster address
+ $rrset{data} =~ s{^\S+\s+\K(\S+[^.])(?=\s)}{$1.$origin};
+ }
+
+ # bei einigen RRs müssen wir die Daten korrigieren
+ when ([qw/MX NS PTR/]) {
+ $rrset{data} .= ".$origin"
+ unless substr($rrset{data}, -1) eq '.';
+ }
+ }
+ my $id = sha512_hex(sort %rrset);
+ push @zone, { id => $id, rrset => \%rrset };
}
}
}
- # list of {
- # id => $id,
+ # list of {
+ # id => $id,
# rrset => { label => …, ttl => …, rrtype => …, data => … }
# }
return @zone;
@@ -79,12 +86,12 @@
sub ttl2h {
my $seconds = shift;
my @out;
- my @units = ( [w => 604800], [d => 86400], [h => 3600], [m => 60], [s => 1]);
+ my @units = ([w => 604800], [d => 86400], [h => 3600], [m => 60], [s => 1]);
foreach (@units) {
- my $x = int($seconds / $_->[1]);
- push @out, "$x$_->[0]" if $x;
- $seconds %= $_->[1] or last;
+ my $x = int($seconds / $_->[1]);
+ push @out, "$x$_->[0]" if $x;
+ $seconds %= $_->[1] or last;
}
return join '', @out;
@@ -94,49 +101,55 @@
my $ttl = shift;
my $out;
my %factor = (
- w => 604800,
- d => 86400,
- h => 3600,
- m => 60,
- s => 1,
+ w => 604800,
+ d => 86400,
+ h => 3600,
+ m => 60,
+ s => 1,
);
while ($ttl =~ m{(\d+)([wdhms])}g) {
- $out += $1 * $factor{$2};
+ $out += $1 * $factor{$2};
}
return $out // $ttl;
}
sub nice {
+
# get a list of { id => $id, rrset => \%rrset }
- my @zone =
- sort { length $a->{label} <=> length $b->{label} or $a->{label}
- cmp $b->{label}} map { $_->{rrset} } @_;
+ my @zone =
+ sort {
+ length $a->{label} <=> length $b->{label}
+ or $a->{label}
+ cmp $b->{label}
+ } map { $_->{rrset} } @_;
my @out;
my $origin = (grep { $_->{rrtype} eq 'SOA' } @zone)[0]->{label};
- my $ttl = (grep { $_->{rrtype} eq 'SOA' } @zone)[0]->{ttl};
+ my $ttl = (grep { $_->{rrtype} eq 'SOA' } @zone)[0]->{ttl};
my $l1 = (sort map { index $_->{label}, '.' } @zone)[-1];
my $l2 = (sort map { length $_->{rrtype} } @zone)[-1];
- push @out, "\$ORIGIN $origin",
- "\$TTL " . ttl2h($ttl);
+ push @out, "\$ORIGIN $origin", "\$TTL " . ttl2h($ttl);
my $print = sub {
- my %r = %{+shift};
- state $last_label;;
+ my %r = %{ +shift };
+ state $last_label;
- $r{label} = '@' if $r{label} eq $origin;
- $r{label} =~ s{\.\Q$origin\E$}{};
- $r{data} =~ s{\.\Q$origin\E$}{} if $r{rrtype} ~~ [qw(MX SOA PTR)];
+ $r{label} = '@' if $r{label} eq $origin;
+ $r{label} =~ s{\.\Q$origin\E$}{};
+ $r{data} =~ s{\.\Q$origin\E$}{} if $r{rrtype} ~~ [qw(MX SOA PTR)];
$r{ttl} = $r{ttl} == $ttl ? '' : ttl2h($r{ttl});
- $r{label} = do {
- if (defined $last_label and $r{label} eq $last_label) { '' }
- else { $last_label = $r{label} }
- };
-
- return sprintf '%-*s %6s %-*s %s',
- $l1 => $r{label}, $r{ttl}, $l2 => $r{rrtype}, $r{data};
+ $r{label} = do {
+ if (defined $last_label and $r{label} eq $last_label) { '' }
+ else { $last_label = $r{label} }
+ };
+
+ return sprintf '%-*s %6s %-*s %s',
+ $l1 => $r{label},
+ $r{ttl},
+ $l2 => $r{rrtype},
+ $r{data};
};
push @out, $print->($_) foreach @zone;
return join "\n", @out;
@@ -157,15 +170,17 @@
sub main {
my ($file) = @_;
- my @zone1 = grep {
- # get { id => $id, rrset => \%rrset }
- not $_->{rrset}{rrtype} ~~ [qw(RRSIG NSEC3 NSEC3PARAM NSEC DNSKEY TSIG)]
- #$_->{rrset}{rrtype} ~~ [qw(SOA NS MX)]
+ my @zone1 = grep {
+
+ # get { id => $id, rrset => \%rrset }
+ not $_->{rrset}{rrtype} ~~ [qw(RRSIG NSEC3 NSEC3PARAM NSEC DNSKEY TSIG)]
+
+ #$_->{rrset}{rrtype} ~~ [qw(SOA NS MX)]
} parse($file);
my $tmp = File::Temp->new();
$tmp->print(nice @zone1);
$tmp->close();
- system $ENV{EDITOR}// 'vi' => $tmp->filename;
+ system $ENV{EDITOR} // 'vi' => $tmp->filename;
my @zone2 = parse($tmp->filename);
delta(\@zone1, \@zone2);
exit;