--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/vidns Tue May 20 00:13:19 2014 +0200
@@ -0,0 +1,93 @@
+#! /usr/bin/perl
+use 5.010;
+use strict;
+use warnings;
+use File::Temp;
+use Smart::Comments;
+
+sub parse {
+ my $file = shift;
+ my @lines = split /\n/, do {
+ local $/ = undef;
+ local @ARGV = $file;
+ <>;
+ };
+
+ my @zone;
+
+ foreach (@lines) {
+ given ($_) {
+ when (m{^;}) { next }
+ when (
+ m{^(?<label>\S+)
+ \s+(?<ttl>\S+(?=\s+))
+ \s+(?:(?:IN|ANY)\s+)?(?<rr>\S+(?=\s+))
+ \s+(?<data>.*)
+ }x
+ )
+ {
+ push @zone, {
+ label => $+{label},
+ ttl => $+{ttl},
+ rr => uc $+{rr},
+ data => $+{data},
+ };
+ }
+ }
+ }
+
+ return @zone;
+
+}
+
+sub nice {
+ my @zone =
+ sort { length $a->{label} <=> length $b->{label} or $a->{label} cmp $b->{label}}
+ grep { !($_->{rr} ~~ [qw(RRSIG NSEC3 NSEC3PARAM NSEC DNSKEY TSIG)]) } @_;
+
+ my $origin = (grep { $_->{rr} eq 'SOA' } @zone)[0]->{label};
+ my $ttl = (grep { $_->{rr} eq 'SOA' } @zone)[0]->{ttl};
+ print "\$ORIGIN $origin\n";
+ print "\$TTL $ttl\n";
+
+ my $print = sub {
+ my $r = shift;
+ state $l1 = (sort map { length $_->{label} } @zone)[-1];
+ state $l2 = (sort map { length $_->{rr} } @zone)[-1];
+ state $last_label;
+
+ my $label = $r->{label} eq $origin ? '@' : $r->{label};
+ $label =~ s{\.\Q$origin\E$}{};
+
+ my $data = $r->{data};
+ if ($r->{rr} ~~ [qw(MX SOA PTR)]) {
+ $data =~ s{\.\Q$origin\E$}{};
+ }
+
+ my $ttl = $r->{ttl} == $ttl ? '' : $r->{ttl};
+
+ my $rc = sprintf "%-*s %6s %-*s %s\n",
+ $l1 => defined $last_label && $label eq $last_label ? '' : $label,
+ $ttl, $l2 => $r->{rr}, $data;
+ $last_label = $label;
+ return $rc;
+ };
+ foreach (@zone) {
+ print $print->($_);
+ }
+ return 0;
+}
+
+sub main {
+ my ($file) = @_;
+ my @zone = parse($file);
+ print nice(@zone);
+ exit;
+ #foreach (map {$_->[1]} @zone) {
+# next if not %{$_};
+# next if $_->{rr} ~~ [qw(DNSKEY RRSIG NSEC3 NSECPARAM NSEC)];
+# say $_->{data};
+# }
+}
+
+exit main(@ARGV) if not caller;