equal
deleted
inserted
replaced
|
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; |