vidns
changeset 0 69882b806c3c
child 1 5f07e5c283c1
equal deleted inserted replaced
-1:000000000000 0:69882b806c3c
       
     1 #! /usr/bin/perl
       
     2 use 5.010;
       
     3 use strict;
       
     4 use warnings;
       
     5 use File::Temp;
       
     6 use Smart::Comments;
       
     7 
       
     8 sub parse {
       
     9     my $file = shift;
       
    10     my @lines = split /\n/, do { 
       
    11 	local $/ = undef;
       
    12 	local @ARGV = $file;
       
    13 	<>;
       
    14     };
       
    15 
       
    16     my @zone;
       
    17 
       
    18     foreach (@lines) {
       
    19         given ($_) {
       
    20             when (m{^;}) { next }
       
    21             when (
       
    22                 m{^(?<label>\S+)
       
    23 		    \s+(?<ttl>\S+(?=\s+))
       
    24 		    \s+(?:(?:IN|ANY)\s+)?(?<rr>\S+(?=\s+))
       
    25 		    \s+(?<data>.*)
       
    26 		  }x
       
    27               )
       
    28             {
       
    29 		push @zone, {
       
    30                         label => $+{label},
       
    31                         ttl   => $+{ttl},
       
    32                         rr    => uc $+{rr},
       
    33                         data  => $+{data},
       
    34 		};
       
    35             }
       
    36         }
       
    37     }
       
    38 
       
    39     return @zone;
       
    40 
       
    41 }
       
    42 
       
    43 sub nice {
       
    44     my @zone = 
       
    45 	sort { length $a->{label} <=> length $b->{label} or $a->{label} cmp $b->{label}}
       
    46 	grep { !($_->{rr} ~~ [qw(RRSIG NSEC3 NSEC3PARAM NSEC DNSKEY TSIG)]) } @_;
       
    47 
       
    48     my $origin = (grep { $_->{rr} eq 'SOA' } @zone)[0]->{label};
       
    49     my $ttl = (grep { $_->{rr} eq 'SOA' } @zone)[0]->{ttl};
       
    50     print "\$ORIGIN $origin\n";
       
    51     print "\$TTL $ttl\n";
       
    52 
       
    53     my $print = sub {
       
    54 	my $r = shift;
       
    55 	state $l1 = (sort map { length $_->{label} } @zone)[-1];
       
    56 	state $l2 = (sort map { length $_->{rr} } @zone)[-1];
       
    57 	state $last_label;
       
    58 
       
    59 	my $label = $r->{label} eq $origin ? '@' : $r->{label};
       
    60 	$label =~ s{\.\Q$origin\E$}{};
       
    61 
       
    62 	my $data = $r->{data};
       
    63 	if ($r->{rr} ~~ [qw(MX SOA PTR)]) {
       
    64 	    $data =~ s{\.\Q$origin\E$}{};
       
    65 	}
       
    66 
       
    67 	my $ttl = $r->{ttl} == $ttl ? '' : $r->{ttl};
       
    68 	
       
    69 	my $rc = sprintf "%-*s %6s %-*s    %s\n",
       
    70 	    $l1 => defined $last_label && $label eq $last_label ? '' : $label,
       
    71 	    $ttl, $l2 => $r->{rr}, $data;
       
    72 	$last_label = $label;
       
    73 	return $rc;
       
    74     };
       
    75     foreach (@zone) {
       
    76 	print $print->($_);
       
    77     }
       
    78     return 0;
       
    79 }
       
    80 
       
    81 sub main {
       
    82     my ($file) = @_;
       
    83     my @zone = parse($file);
       
    84     print nice(@zone);
       
    85     exit;
       
    86     #foreach (map {$_->[1]} @zone) {
       
    87 #	next if not %{$_};
       
    88 #	next if $_->{rr} ~~ [qw(DNSKEY RRSIG NSEC3 NSECPARAM NSEC)];
       
    89 #	say $_->{data};
       
    90 #    }
       
    91 }
       
    92 
       
    93 exit main(@ARGV) if not caller;