[snapshot]
authorHeiko Schlittermann (JUMPER) <hs@schlittermann.de>
Tue, 20 May 2014 00:13:19 +0200
changeset 0 69882b806c3c
child 1 5f07e5c283c1
[snapshot]
vidns
--- /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;