Moved to git@git.schlittermann.de:dnsvi.git default tip
authorHeiko Schlittermann <hs@schlittermann.de>
Sat, 13 Aug 2016 00:01:48 +0200
changeset 106 140d7537105e
parent 105 9069ce49fd83
Moved to git@git.schlittermann.de:dnsvi.git
Build.PL
INSTALL
MANIFEST
MANIFEST.SKIP
README
bin/dnsvi
debian/changelog
debian/compat
debian/control
debian/copyright
debian/rules
debian/source/format
lib/DNS/Vi.pm
t/10-dnsvi.t
t/20-cname-change.t
t/20-reverse-dns.t
t/samples/a
t/samples/axfr
t/samples/b
t/samples/c
t/samples/d
t/samples/frey-1
t/samples/frey-2
--- a/Build.PL	Thu Jul 14 10:30:58 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-use Module::Build;
-
-Module::Build->new(
-    dist_name         => 'dnsvi',
-    dist_version_from => 'bin/dnsvi',
-    dist_abstract     => 'simple script to edit dynamic DNS zones',
-    script_files      => ['bin/dnsvi'],
-    requires          => {
-        perl            => 5.010,
-        'Term::ReadKey' => '0',
-        'Net::DNS'      => '0.66',
-    }
-)->create_build_script;
--- a/INSTALL	Thu Jul 14 10:30:58 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-Build
------
-
-    perl Build.PL
-    ./Build
-    ./Build test
-
-Install
--------
-
-    ./Build fakeinstall
-    ./Build install
-
-And now have fun :)
--- a/MANIFEST	Thu Jul 14 10:30:58 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,24 +0,0 @@
-.hgignore
-.hgsigs
-.hgtags
-bin/dnsvi
-Build.PL
-debian/changelog
-debian/compat
-debian/control
-debian/copyright
-debian/rules
-debian/source/format
-INSTALL
-lib/DNS/Vi.pm
-MANIFEST			This list of files
-t/10-dnsvi.t
-t/20-cname-change.t
-t/20-reverse-dns.t
-t/samples/a
-t/samples/axfr
-t/samples/b
-t/samples/c
-t/samples/d
-t/samples/frey-1
-t/samples/frey-2
--- a/MANIFEST.SKIP	Thu Jul 14 10:30:58 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +0,0 @@
-
-#!start included /home/heiko/perl5/lib/perl5/ExtUtils/MANIFEST.SKIP
-# Avoid version control files.
-\bRCS\b
-\bCVS\b
-\bSCCS\b
-,v$
-\B\.svn\b
-\B\.git\b
-\B\.gitignore\b
-\b_darcs\b
-\B\.cvsignore$
-
-# Avoid VMS specific MakeMaker generated files
-\bDescrip.MMS$
-\bDESCRIP.MMS$
-\bdescrip.mms$
-
-# Avoid Makemaker generated and utility files.
-\bMANIFEST\.bak
-\bMakefile$
-\bblib/
-\bMakeMaker-\d
-\bpm_to_blib\.ts$
-\bpm_to_blib$
-\bblibdirs\.ts$         # 6.18 through 6.25 generated this
-
-# Avoid Module::Build generated and utility files.
-\bBuild$
-\b_build/
-\bBuild.bat$
-\bBuild.COM$
-\bBUILD.COM$
-\bbuild.com$
-
-# Avoid temp and backup files.
-~$
-\.old$
-\#$
-\b\.#
-\.bak$
-\.tmp$
-\.#
-\.rej$
-
-# Avoid OS-specific files/dirs
-# Mac OSX metadata
-\B\.DS_Store
-# Mac OSX SMB mount metadata files
-\B\._
-
-# Avoid Devel::Cover and Devel::CoverX::Covered files.
-\bcover_db\b
-\bcovered\b
- 
-# Avoid MYMETA files
-^MYMETA\.
-#!end included /home/heiko/perl5/lib/perl5/ExtUtils/MANIFEST.SKIP
-
-# Avoid configuration metadata file
-^MYMETA\.
-
-# Avoid Module::Build generated and utility files.
-\bBuild$
-\bBuild.bat$
-\b_build
-\bBuild.COM$
-\bBUILD.COM$
-\bbuild.com$
-^MANIFEST\.SKIP
-
-# Avoid archives of this distribution
-\bdnsvi-[\d\.\_]+
-
-\bK.*
-^\.hg/
-^debian/dnsvi.*
-^debian/files
-^CHANGES$
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/README	Sat Aug 13 00:01:48 2016 +0200
@@ -0,0 +1,1 @@
+see https://git.schlittermann.de/cgit/dnsvi
--- a/bin/dnsvi	Thu Jul 14 10:30:58 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,244 +0,0 @@
-#! /usr/bin/perl
-#line 3
-# Copyright: (C) 2014-2015 Heiko Schlittermann <hs@schlittermann>
-# This program is released unter the Terms of the GPL.
-use 5.10.1;
-use strict;
-use warnings;
-use if $ENV{DEBUG} => 'Smart::Comments';
-use Getopt::Long;
-use Pod::Usage;
-use File::Copy;
-use DNS::Vi;
-use if $] >= 5.020, experimental => 'smartmatch';
-
-our $VERSION = '1.0';
-
-sub slurp {
-    local $/    = undef;
-    local @ARGV = @_;
-    <>;
-}
-
-sub main {
-    my %o = (
-        local => undef,
-        key   => (grep { -f } glob "$ENV{HOME}/.dnsvi/default/K*key")[0]
-          // (undef, local => 1),
-        server => undef,
-        debug  => undef,
-        editor => $ENV{EDITOR} // 'vi',
-        skip   => [qw/RRSIG NSEC3 NSEC3PARAM NSEC DNSKEY TSIG/],
-    );
-
-    GetOptions(
-        'k|key=s'    => \$o{key},
-        's|server=s' => \$o{server},
-        'd|debug!'   => \$o{debug},
-        'l|local!'   => \$o{local},
-        'editor=s'   => \$o{editor},
-      )
-      && @ARGV >= 1
-      or pod2usage();
-
-
-    my %auth = get_auth_info shift @ARGV, $o{server};
-    my $zone = $auth{name};
-
-    $o{server} = $o{local} ? 'localhost' : $auth{mname}
-      if not defined $o{server};
-
-    my @dig = (
-        dig => 'AXFR',
-        defined $o{key} ? (-k => $o{key}) : (),
-        defined $o{server} ? ("\@$o{server}") : (),
-        $zone
-    );
-
-    my @zone1 = parse($_ = `@dig`, { -skip => $o{skip} })
-      or die "Empty zone\n";
-
-  UNDO:
-    my @zone2 = @zone1;
-    my $backup;    # it's a tmp file containing the original
-
-  EDIT:
-    @zone2 = do {
-        if (my $file = shift @ARGV) {
-            parse(slurp($file), { -skip => $o{skip} });
-        }
-        else {
-            edit(
-                @zone2,
-                {
-                    -skip   => $o{skip},
-                    -editor => $o{editor},
-                    -backup => \$backup
-                }
-            );
-        }
-    };
-    ### @zone2
-
-    my %delta = delta(\@zone1, \@zone2);
-    if (!%delta) {
-        say 'nothing changed';
-        return 0;
-    }
-
-  VIEW:
-    if ($_ eq 'v' or (map { @{$_} } values %delta) < 10) {
-        say 'The following changes need your confirmation.';
-        say join "\n", show(@delta{qw/add del/});
-    }
-    else {
-        say 'added: ', 0 + @{ $delta{add} }, ', removed: ',
-          0 + @{ $delta{del} };
-    }
-  CONFIRM:
-    print 'action [yqQvVeu?] ?';
-    $_ = get_key;
-
-    given ($_) {
-        when ('y') { }
-        when ('q') { }
-        when ('V') { }
-        when ('Q') { return 1 }
-        when ('e') { goto EDIT }
-        when ('v') { goto VIEW }
-        when ('u') { goto UNDO }
-        when ('?') {
-            print <<_;
-  y -- yes: submit changes and exit
-  q -- quit: save changes as ",dnsvi-$$"
-  Q -- quit: discard changes and exit
-  v -- view changes
-  V -- view changes as nsupdate commands
-  e -- edit again
-  u -- undo and edit again
-  ? -- what?
-_
-            goto CONFIRM;
-        }
-        default { goto CONFIRM }
-    }
-
-    /^[yV]$/ and update(
-        \@zone1,
-        @delta{qw/add del/},
-        {
-            $_ eq 'V' ? (-dry => 1) : (),
-            -server => $o{server},
-            -local  => $o{local},
-            -debug  => $o{debug},
-            -key    => $o{key}
-        }
-      )
-      or do {
-        if ($backup) {
-            copy($backup->filename, ",dnsvi-$$")
-              and say "Saved as ',dnsvi-$$'";
-        }
-      };
-
-    goto CONFIRM if $_ eq 'V';
-
-    return 0;
-}
-
-exit main(@ARGV) if not caller;
-
-__END__
-
-=head1 NAME
-
- dnsvi -- editor for dynamically maintained zones
-
-=head1 SYNOPSIS
-
- dnsvi [[-l] | [[-k key] [-s server]]] [-d] <zone> [<file>]
-
-=head1 DESCRIPTION
-
-This tools supports you in maintaining a dynamic zone. Normally you'll
-use it with the name of zone. For batch mode you may use it with an
-additional parameter, die edited zone file.
-
-=head2 OPTIONS
-
-=over
-
-=item B<-l>|B<--local> 
-
-Local mode, when running on the server where the updates need to go to.
-But still zone transfers need to be enabled! (default: on, if not
-default key file is found, otherwise off)
-
-=item B<-s>|B<--server> B<server-name>
-
-The name of the server to contact for the AXFR and the update.
-(default: main nameserver from the SOA record)
-
-=item B<-k>|B<--key> B<key-file>
-
-The name of the key file we need for TSIG (the AXFR will use it,
-as well as the update). (default: F<~/.dnsvi/default/K*key)
-
-To create such a key you may use 
-
-    dnssec-keygen -a HMAC-MD5 -b 512 -n USER heiko
-
-Then copy the resulting files somewhere (you'll need both files).
-On the server side include the key into to configuration:
-
-    key "<name>" {
-	algorithm   HMAC-MD5;
-	secret	    "<the secret from the created key file>"
-    };
-
-Per zone you should use 
-
-    zone "<zone>" {
-	...
-	update-policy {
-	    grant local-ddns zonesub any;   // support for -l
-	    grant <key-name> zonesub;	    // support for -k
-	};
-	...
-    };
-
-=item B<-d>
-
-This option enables debugging of C<nsupdate>. (default: off)
-
-=back
-
-=head1 EXAMPLES
-
-The usage is quite straight forward:
-
-    dnsvi example.com
-    dnsvi sub.sub.sub.example.com
-    dnsvi 212.80.235.130
-
-If something went wrong and you need to re-open your backup:
-
-    dnsvi example.com ,dnsvi-815
-
-=head1 PREREQUISITES
-
-We need some tools to be installed:
-
-=over
-
-=item B<dig>
-
-The domain information groper is used for the zone transfer currently.
-
-=item B<nsupdate>
-
-The nsupdate tool is used to send the updates back to the server.
-
-=back
-
-=cut
--- a/debian/changelog	Thu Jul 14 10:30:58 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,121 +0,0 @@
-dnsvi (1.3) stable; urgency=medium
-
-  * Use user supplied server for get_auth_info too
-
- -- Heiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>  Thu, 14 Jul 2016 10:30:52 +0200
-
-dnsvi (1.2) stable; urgency=medium
-
-  * better regex for removing the comments:
-
- -- Heiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>  Thu, 09 Apr 2015 22:07:03 +0200
-
-dnsvi (1.1) stable; urgency=medium
-
-  * less verbose for dh_make:
-  * add tw=0 at the very end of the zone file:
-  * sort for comparison!
-  * Added test for DKIM TXT record:
-  * allow ; in ".." lines:
-
- -- Heiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>  Thu, 09 Apr 2015 13:55:47 +0200
-
-dnsvi (1.0) stable; urgency=medium
-
-  * Now we can edit reverse zones!:
-  * [perltidy]:
-  * updated dependeny on Net::DNS:
-  * updated the info about needed files:
-  * skip the CHANGES file:
-  * put the depencies there:
-  * more docu:
-
- -- Heiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>  Wed, 28 Jan 2015 23:55:06 +0100
-
-dnsvi (0.10) stable; urgency=medium
-
-  * fixed mising backup after reloading a ,dnsvi* file:
-
- -- Heiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>  Wed, 28 Jan 2015 12:51:11 +0100
-
-dnsvi (0.9) stable; urgency=medium
-
-  * really, no experimental in bin/dnsvi:
-
- -- Heiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>  Tue, 27 Jan 2015 22:07:10 +0100
-
-dnsvi (0.8) stable; urgency=medium
-
-  * use smartmatch experimental if >=5.20:
-
- -- Heiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>  Tue, 27 Jan 2015 22:04:58 +0100
-
-dnsvi (0.7) stable; urgency=medium
-
-  * use default -k … and -l …: check $HOME/.dnsvi/default/K*key,
-    otherwise use -l
-  * added more option to confirmation dialog:
-
- -- Heiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>  Tue, 27 Jan 2015 21:55:33 +0100
-
-dnsvi (0.6) stable; urgency=medium
-
-  * more tests:
-  * [merged] from branch deb:
-  * sort order in a more prominent place:  Now we have a %ORDER global
-    variable in the package DNS::Vi
-  * fixed trailing spaces:
-  * cope with additional spaces in soa records:
-  * cope with continuation lines:
-  * deal with very short primary names in SOA record:
-  * changed the delta function: Now it returns a hash, not an array.
-  * cosmetical changes:
-  * fixed the cname change bug (reported by m.f.):
-  * Hint about the SOA record:
-
- -- Heiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>  Wed, 21 Jan 2015 23:09:39 +0100
-
-dnsvi (0.5) stable; urgency=low
-
-  * Changed the sort order.: When displaying the zone we sort in a way
-    where same domains are kept together with their subdomains.  We do
-    this by reverting the label and sorting these reverted labels.
-
- -- Heiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>  Mon, 08 Dec 2014 10:23:43 +0100
-
-dnsvi (0.4) stable; urgency=low
-
-  * section added 
-
- -- Heiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>  Fri, 14 Nov 2014 11:41:25 +0100
-
-dnsvi (0.3) stable; urgency=low
-
-  * [merged] from debian:
-  * ignore CHANGES:
-  * extended description
-  * added the copyright
-
- -- Heiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>  Fri, 14 Nov 2014 10:55:39 +0100
-
-dnsvi (0.2) stable; urgency=low
-
-  * fixed manifesto:
-  * fixed the manifesto again:
-  * [savepoint]:
-  * built the first packate for tests:
-  * fixed lintian warning about standards version:
-
- -- Heiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>  Fri, 14 Nov 2014 09:59:58 +0100
-
-dnsvi (0.1) stable; urgency=low
-
-  * bug fix release
-
- -- Heiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>  Thu, 13 Nov 2014 23:05:31 +0100
-
-dnsvi (0.0) stable; urgency=low
-
-  * Initial release.
-
- -- Heiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>  Thu, 05 Jun 2014 21:09:29 +0200
--- a/debian/compat	Thu Jul 14 10:30:58 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-9
--- a/debian/control	Thu Jul 14 10:30:58 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-Source: dnsvi
-Build-Depends: debhelper (>= 9)
-Maintainer: Heiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>
-Standards-Version: 3.9.4
-Section: admin
-Priority: standard
-
-Package: dnsvi
-Architecture: all
-Section: admin
-Priority: standard
-Depends: perl (>= 5.14), dnsutils, libnet-dns-perl, libterm-readkey-perl
-Description: DNS (domain) zone editor
- This tools allows you edit a dynamically maintained DNS zone,
- either locally or remote. The update of the zone is done via
- nsupdate, secured by TSIG.
--- a/debian/copyright	Thu Jul 14 10:30:58 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-Copyright (C) 2014 Heiko Schlittermann <hs@schlittermann.de>
-
-This program is free software; you may redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-This is distributed in the hope that it will be useful, but without
-any warranty; without even the implied warranty of merchantability or
-fitness for a particular purpose. See the GNU General Public License
-for more details.
-
-A copy of the GNU General Public License version 3 is available as
-/usr/share/common-licenses/GPL-3 in the Debian GNU/Linux distribution
-or at http://www.gnu.org/licenses/old-licenses/gpl-3.0.html.
-You can also obtain it by writing to the Free Software Foundation, Inc.,
-51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
-
--- a/debian/rules	Thu Jul 14 10:30:58 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-#! /usr/bin/make -f
-
-export PERL_MM_OPT =
-export PERL_MB_OPT =
-export PERL5LIB =
-
-#export DH_VERBOSE = 1
-
-%:
-	dh $@
-
-override_dh_installchangelogs:
-	dh_installchangelogs CHANGES
--- a/debian/source/format	Thu Jul 14 10:30:58 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-3.0 (native)
--- a/lib/DNS/Vi.pm	Thu Jul 14 10:30:58 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,317 +0,0 @@
-package DNS::Vi;
-use 5.0101;
-use strict;
-use warnings;
-use if $ENV{DEBUG} // '' eq 'dnsvi' => 'Smart::Comments';
-use Digest::SHA qw(sha512_hex);
-use File::Temp;
-use Net::DNS;
-use Term::ReadKey;
-use base 'Exporter';
-use if $] >= 5.020, experimental => 'smartmatch';
-
-our @EXPORT = qw(ttl2h h2ttl parse delta nice edit update show get_key
-  get_auth_info);
-our @EXPORT_OK = ();
-
-# the sort order for the records of the same label
-my %ORDER = map { state $n = 0; $_ => ++$n } qw(SOA NS TXT MX A AAAA SSHFP);
-
-sub h2ttl(_);
-
-# input $arg - hash with options
-#       $data - a long string with the zone data
-sub parse {
-    my %arg   = %{ pop @_ } if ref $_[-1] eq ref {};
-    my $data  = shift;
-    my @lines = split /\n/, $data;
-
-    my @zone;
-    my ($origin, $ttl, $last_label, $soa_seen);
-
-    $_ = '';
-    foreach (@lines) {
-	# simplificated comment remover
-	# after the comment character no '"' is allowed!
-#        s{^\s*;.*$}{};		  # strip comment lines
-#	s{\s*;[^"]*$}{};	  # strip trailing comments
-
-	# see https://regex101.com/r/cG6fK3/2
- 	s{\s*(?:;)(?:(?:[^"]|"[^"]*")*$)}{};
-        state $line;
-        if (my $range = /(.*)\(\s*$/ .. /(.*)\)\s*/) {
-            $line .= defined $1 ? $1 : $_;
-            next unless $range =~ /E0$/;
-        }
-        if (defined $line) {
-            $_    = $line;    # accumulated continuation line
-            $line = undef;
-        }
-        s{\s*$}{};            # strip off trailing spaces
-        given ($_) {
-            when (m{^\s*$})                { next }
-            when (m{^\s*\$ORIGIN\s+(\S+)}) { $origin = $1 }
-            when (m{^\s*\$TTL\s+(\S+)})    { $ttl = $1 }
-            when (
-                m{^(?:(?<label>\S+)(?=\s))?
-		    (?:\s+(?<ttl>\d[\dwdmhs]*(?=\s+)))?
-		    (?:\s+(?:(?:IN|ANY)\s+)?(?<rrtype>[a-z]\S*(?=\s+)))
-		    \s+(?<data>.*)
-		  }ix
-              )
-            {
-                my %rrset = (
-                    label => $last_label =
-                      defined $+{label}
-                    ? $+{label} eq '@'
-                          ? $origin
-                          : $+{label}
-                    : $last_label,
-                      ttl => h2ttl($+{ttl} // $ttl),
-                      rrtype => uc $+{rrtype},
-                      data   => $+{data},
-                );
-                next if $rrset{rrtype} ~~ $arg{-skip};
-
-                if ($rrset{rrtype} eq 'SOA') {
-                    next if $soa_seen++;
-                }
-
-                # 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};
-                        my ($primary, $hostmaster, $serial, $refresh, $retry,
-                            $expire, $minttl)
-                          = split ' ', $rrset{data};
-
-                        $_ .= ".$origin" foreach grep !/\.$/ => $primary,
-                          $hostmaster;
-
-                        $rrset{data} = join ' ',
-                          $primary, $hostmaster, $serial,
-                          map { h2ttl } $refresh, $retry, $expire, $minttl;
-                    }
-
-                    # bei einigen RRs müssen wir die Daten korrigieren
-                    when ([qw/CNAME MX NS PTR SOA/]) {
-                        $rrset{data} =~ s/\@/$origin/g;
-                        $rrset{data} .= ".$origin"
-                          unless substr($rrset{data}, -1) eq '.';
-                    }
-                }
-                my $id = sha512_hex(join "\0",
-                    map { $_ => $rrset{$_} } sort keys %rrset);
-                push @zone, { id => $id, rrset => \%rrset };
-                ### x: $zone[-1]
-            }
-        }
-    }
-
-    return @zone;
-}
-
-sub ttl2h {
-    my $seconds = shift;
-    my @out;
-    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;
-    }
-
-    return join '', @out;
-}
-
-sub h2ttl(_) {
-    my $ttl = shift;
-    my $out;
-    my %factor = (
-        w => 604800,
-        d => 86400,
-        h => 3600,
-        m => 60,
-        s => 1,
-    );
-
-    while ($ttl =~ m{(\d+)([wdhms])}g) {
-        $out += $1 * $factor{$2};
-    }
-
-    return $out // $ttl;
-}
-
-sub nice {
-
-    # get a list of { id => $id, rrset => \%rrset }
-    # we do a schwartz transformation here
-    # [ reverse LABEL, RRSET ]
-    my @zone = map { $_->[1] }
-      sort {
-             $a->[0] cmp $b->[0]
-          or length $a->[1]{label} <=> length $b->[1]{label}
-          or ($ORDER{ $a->[1]{rrtype} } // 99)
-          <=> ($ORDER{ $b->[1]{rrtype} } // 99)
-      }
-      map { [scalar reverse($_->{label}), $_] } map { $_->{rrset} } @_;
-
-    my @out;
-    my $origin = (grep { $_->{rrtype} eq 'SOA' } @zone)[0]->{label};
-    my $ttl    = (grep { $_->{rrtype} eq 'SOA' } @zone)[0]->{ttl};
-    my $len1 =
-      (sort { $a <=> $b } map { index $_->{label}, '.' } @zone)[-1];
-    my $len2 = (sort { $a <=> $b } map { length $_->{rrtype} } @zone)[-1];
-    push @out, "\$ORIGIN $origin", "\$TTL " . ttl2h($ttl);
-
-    my $print = sub {
-        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(CNAME MX SOA PTR)];
-        $r{data} =~ s{\Q$origin\E$}{\@} if $r{rrtype} ~~ [qw(CNAME MX)];
-        $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',
-          $len1 => $r{label},
-          $r{ttl},
-          $len2 => $r{rrtype},
-          $r{data};
-    };
-    push @out, '; IF YOU EDIT the SOA record, INCREASE the serial number too!';
-    push @out, $print->($_) foreach @zone;
-    return join "\n", @out, '';
-}
-
-sub delta {
-    my ($zone1, $zone2) = @_;
-    my %zone1 = map { $_->{id}, $_->{rrset} } @$zone1;
-    my %zone2 = map { $_->{id}, $_->{rrset} } @$zone2;
-    my @keys1 = keys %zone1;
-    my @keys2 = keys %zone2;
-    delete @zone1{@keys2};
-    delete @zone2{@keys1};
-
-    my (@add, @del);
-    push @add, "@{$_}{qw/label ttl rrtype data/}" foreach values %zone2;
-    push @del, "@{$_}{qw/label ttl rrtype data/}" foreach values %zone1;
-
-    return () if (!@add and !@del);
-    return (add => \@add, del => \@del);
-}
-
-sub edit {
-    my %arg = %{ pop @_ } if ref $_[-1] eq ref {};
-    my @zone = @_;
-
-    # first make a backup copy
-    my $tmp = File::Temp->new();
-    $tmp->print(nice @zone);
-    $tmp->say('; vim:tw=0:');
-    $tmp->flush();
-
-    system $arg{-editor} => $tmp->filename;
-    $tmp->seek(0, 0);
-    ${ $arg{-backup} } = $tmp if $arg{-backup};
-    return parse(do { local $/ = undef; <$tmp> }, { -skip => $arg{-skip} });
-}
-
-sub show {
-    my ($add, $del) = @_;
-    my @out = ((map { " - $_ " } @$del), (map { " + $_ " } @$add));
-    return @out;
-}
-
-sub update {
-    my %arg = %{ pop @_ } if ref $_[-1] eq ref {};
-    my ($zone1, $add, $del) = @_;
-
-    my $orig_soa =
-      (grep { $_->{rrtype} eq 'SOA' } map { $_->{rrset} } @$zone1)[0];
-
-    my @cmds = (
-        $arg{-local} ? () : "server $arg{-server}",
-        "prereq yxrrset @{$orig_soa}{qw{label rrtype data}}",
-        (map { "update delete $_" } @$del),
-        (map { "update add $_" } @$add),
-        'send',
-        'answer',
-    );
-    if ($arg{-dry}) {
-        return say join "\n", '', @cmds, '' if $arg{-dry};
-    }
-    my @nsupdate = (
-        'nsupdate',
-        defined $arg{-debug} ? ('-d') : (),
-        defined $arg{-key} ? (-k => $arg{-key}) : (),
-        defined $arg{-local} ? ('-l') : (),
-    );
-
-    open(my $nsupdate, '|-') or do {
-        exec @nsupdate;
-        die "Can't exec @nsupdate: $!\n";
-    };
-    say $nsupdate join "\n", @cmds;
-    close($nsupdate);
-    say "nsupdate returned $?";
-    return $? ? undef : 1;
-}
-
-sub save {
-    my ($zone, $file) = @_;
-    open(my $fh, '>', $file) or die "Can't open >$file: $!\n";
-    print $fh nice @$zone;
-    close($fh);
-
-}
-
-sub get_key {
-    ReadMode 'cbreak';
-    local $/ = \1;
-    my $x = <STDIN>;
-    ReadMode 'restore';
-    print "\n";
-    return $x;
-}
-
-sub get_auth_info {
-    my $name = shift;
-    my $server = shift;
-    my %auth = (zone => undef, master => undef);
-    state $resolver = Net::DNS::Resolver->new(
-        defined $server ? (nameservers => [$server]) : ()
-    );
-    my $response = $resolver->send($name, 'SOA')
-      or die $resolver->errorstring, "\n";
-
-    #    use Data::Dumper;
-    #    die Dumper $response;
-
-    if (my @soa = grep { $_->type eq 'SOA' } $response->answer,
-        $response->authority)
-    {
-        die "got multiple soa records\n" if @soa > 1;
-        my $soa = $soa[0];
-        return (
-            name  => $soa->name,
-            mname => $soa->mname,
-        );
-    }
-
-    return $response->authority;
-}
-
-1;
--- a/t/10-dnsvi.t	Thu Jul 14 10:30:58 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,147 +0,0 @@
-#! perl
-
-use 5.010;
-use Test::More;
-use strict;
-use warnings;
-use File::Basename;
-
-use_ok 'DNS::Vi' or BAIL_OUT 'DNS::Vi not found!';
-can_ok 'DNS::Vi', qw(ttl2h h2ttl parse nice delta edit update show);
-
-# TODO: more tests!
-is ttl2h(86400), '1d',  '-> 1d';
-is h2ttl('1d'),  86400, '<- 1d';
-
-sub slurp {
-    local $/ = undef;
-    open(my $x, '<', shift);
-    return <$x>;
-}
-
-# the expect must match the t/samples/? files
-my %expect = (
-    axfr => {
-        RRSETS => 64,
-        SOA    => 1,
-        NS     => 2,
-        A      => 6,
-        TXT    => 3,
-        AAAA   => 1,
-        MX     => 5,
-    },
-    a => {
-        RRSETS => 32,
-        SOA    => 1,
-        NS     => 16,
-        A      => 9,
-        TXT    => 4,
-        AAAA   => 0,
-        MX     => 0,
-	SOA    => {
-	    'km21.de.' => ['pu.km21.de. hostmaster.schlittermann.de. 1397766411 86400 7200 604800 300'],
-	},
-    },
-    b => {
-        RRSETS => 11,
-        SOA    => {
-	    'km21.de.' => ['pu.schlittermann.de. hostmaster.schlittermann.de. 1397766411 86400 7200 604800 300'],
-	},
-        NS     => 2,
-        A      => 1,
-        TXT    => 3,
-        AAAA   => 0,
-        MX     => 0,
-	CNAME  => {
-	    'foo.km21.de.' => [qw/tte.km21.de./],
-	    'bar.km21.de.' => [qw/tte.km21.de./],
-	    'baz.km21.de.' => [qw/tte.km21.de./],
-	    'faz.km21.de.' => [qw/a.b.c./],
-	},
-    },
-    c => {
-        RRSETS => 12,
-        SOA    => 1,
-        NS     => 2,
-        A      => 2,
-        TXT    => 5,
-        AAAA   => 0,
-        MX     => 2,
-    },
-    d => {
-        RRSETS => 15,
-        SOA    => 1,
-        NS     => 2,
-        A      => [qw/
-	    abc.de.km21.de.
-	    foo.km21.de.
-	    tte.km21.de.
-	    tte.km21.de.
-	    bar.km21.de.
-	/],
-        TXT    => { 
-	    'km21.de.' => [ map { "\"$_\"" }
-		'invoice: self', 
-		'utf8: km21.de', 
-		'start: 1396981300 2014-04-08T20:21:40', 
-	    ],
-	    'tte.km21.de.' => [ map { "\"$_\"" } 'tte', 'tte2' ],
-	},
-        AAAA   => 0,
-        MX     => 2,
-    },
-    'frey-1' => {
-	RRSETS => 6,
-	SOA => { 'example.com.' => ['p.example.com. hostmaster.example.com. 47 3600 900 604800 300'] },
-	A => { 'p.example.com.' => ['1.1.1.1', '2.2.2.2'] },
-	NS => { 'example.com.' => ['p.example.com.'] },
-	CNAME => {
-	    'proxy.mm.frey.example.com.' => ['uxa.frey.example.com.'],
-	    'portal.mm.frey.example.com.'=> ['uxb.frey.example.com.'],
-	},
-    },
-    dkim => {
-	RRSETS => 2,
-	TXT => { 'k1._domainkey.km21.de.' => ['"v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AM"'] },
-	SOA => 1,
-    }
-);
-
-# uniq list of rrtypes we want to test
-my @sets = do {
-    my %h;
-    @h{ map { keys %{$_} } values %expect } = ();
-    grep { $_ ne 'RRSETS' } sort keys %h;
-};
-
-foreach my $sample (sort keys %expect) {
-    my $file = "t/samples/$sample";
-
-    subtest "sample $file" => sub {
-        my %expect = %{ $expect{$sample} };
-        my @zone   = parse(slurp $file);
-        is @zone, $expect{RRSETS} => "$sample: $expect{RRSETS} RRSETS";
-        foreach my $type (@sets) {
-	    if (ref $expect{$type} eq ref[]) {
-		my @entries = sort map { $_->{label} } grep { $_->{rrtype} eq $type } map { $_->{rrset} } @zone;
-		is_deeply \@entries, [sort @{$expect{$type}} ] => 'list of labels';
-	    }
-	    elsif (ref $expect{$type} eq ref{}) {
-		foreach my $label (keys %{ $expect{$type} }) {
-		    my @entries = sort map { $_->{data} } grep { $_->{label} eq $label and $_->{rrtype} eq $type } map { $_->{rrset} } @zone;
-		    is_deeply \@entries, [sort @{ $expect{$type}{$label} }] => 'complete rrsets',
-		}
-	    }
-	    else {
-            is grep({ $_->{rrset}{rrtype} eq $type } @zone),
-		$expect{$type}//0 => "number of $type rrsets";
-	    }
-        }
-
-	my %delta = delta(\@zone, \@zone);
-        is @{$delta{add}}, 0 => 'nothing added';
-        is @{$delta{del}}, 0 => 'nothing deleted';
-      }
-}
-
-done_testing();
--- a/t/20-cname-change.t	Thu Jul 14 10:30:58 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-#! perl
-use strict;
-use warnings;
-use Test::More;
-use DNS::Vi;
-
-sub slurp {
-    local @ARGV = @_;
-    join "\n", <>;
-}
-
-ok my @zone1 = parse(slurp 't/samples/frey-1') => 'got 1st zone';
-ok my @zone2 = parse(slurp 't/samples/frey-2') => 'got 2nd zone';;
-
-ok my %delta = delta(\@zone1, \@zone2) => 'got delta';
-is @{$delta{add}}, 2 => '2 added';
-is @{$delta{del}}, 3 => '3 deleted';
-
-
-done_testing;
--- a/t/20-reverse-dns.t	Thu Jul 14 10:30:58 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-#! perl
-
-use 5.010;
-use Test::More;
-use strict;
-use warnings;
-use File::Basename;
-use Data::Dumper;
-
-use_ok 'DNS::Vi' or BAIL_OUT 'DNS::Vi not found!';
-can_ok 'DNS::Vi', qw(get_auth_info);
-
-is_deeply { get_auth_info('schlittermann.de') },
-  {
-    name  => 'schlittermann.de',
-    mname => 'pu.schlittermann.de'
-  } => 'schlittermann.de';
-
-is_deeply { get_auth_info('kx.schlittermann.de') },
-  {
-    name  => 'kx.schlittermann.de',
-    mname => 'pu.schlittermann.de'
-  } => 'kx.schlittermann.de';
-
-is_deeply { get_auth_info('ssl.schlittermann.de') },
-  {
-    name  => 'schlittermann.de',
-    mname => 'pu.schlittermann.de'
-  } => 'ssl.schlittermann.de';
-
-is_deeply { get_auth_info('www.schlittermann.de') },
-  {
-    name  => 'schlittermann.de',
-    mname => 'pu.schlittermann.de'
-  } => 'www.schlittermann.de';
-
-is_deeply { get_auth_info('no-such-domain.de') },
-  {
-    name  => 'de',
-    mname => 'f.nic.de',
-  } => 'no-such-domain.de';
-
-is_deeply { get_auth_info('212.80.235.130') },
-  {
-    name  => '128-191.235.80.212.in-addr.arpa',
-    mname => 'pu.schlittermann.de'
-  } => '212.80.235.130';
-
-is_deeply { get_auth_info('212.80.235.135') },
-  {
-    name  => '128-191.235.80.212.in-addr.arpa',
-    mname => 'pu.schlittermann.de'
-  } => '212.80.235.135';
-
-is_deeply { get_auth_info('2001:470:72aa:8::12') },
-  {
-    name  => 'a.a.2.7.0.7.4.0.1.0.0.2.ip6.arpa',
-    mname => 'pu.schlittermann.de'
-  } => '2001:470:72aa:8::12';
-
-done_testing;
--- a/t/samples/a	Thu Jul 14 10:30:58 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-$ORIGIN km21.de.
-$TTL 1d
-; do NOT EDIT the SOA records SERIAL number!
-; keep the spaces in the next line!
-@               SOA    pu      hostmaster.schlittermann.de. 1397766411 86400 7200 604800 300
-                NS     hh.schlittermann.de.
-                NS     pu.schlittermann.de.
-                TXT    "invoice: self"
-                TXT    "utf8: km21.de"
-                TXT    "start: 1396981300 2014-04-08T20:21:40"
-foo             TXT    "fooo"
-                A      10.10.10.3
-tte             A      85.214.245.1
-hs12            NS     fivec.lode.km21.de.
-                NS     kivoc.hs12.km21.de.
-                DS     7747 5 1 DD32F9B6FC57CC5F9E991A50B9F4A698BC31B11B
-                DS     7747 5 2 3E2B512F7F4C72DA3C03886572245800A76C5B6C78815EF02B5FD2A1 19ADC74E
-km20            NS     funuz.km20.km21.de.
-                NS     lofax.kt42.km21.de.
-kt42            NS     funuz.km20.km21.de.
-                NS     lofax.kt42.km21.de.
-lode            NS     civik.cinux.km21.de.
-                NS     fivec.lode.km21.de.
-n00b            NS     manup.ichteste.km21.de.
-                NS     zavit.n00b.km21.de.
-cinux           NS     civik.cinux.km21.de.
-                NS     fivec.lode.km21.de.
-ichteste        NS     manup.ichteste.km21.de.
-                NS     zavit.n00b.km21.de.
-fivec.lode        A      192.168.102.105
-funuz.km20        A      192.168.102.233
-kivoc.hs12        A      192.168.102.222
-lofax.kt42        A      192.168.102.201
-zavit.n00b        A      192.168.102.104
-civik.cinux        A      192.168.102.127
-manup.ichteste        A      192.168.102.101
--- a/t/samples/axfr	Thu Jul 14 10:30:58 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-
-; <<>> DiG 9.8.4-rpz2+rl005.12-P1 <<>> @dns.net -k Kheiko.+157+01468.key kugelbus.de axfr
-; (1 server found)
-;; global options: +cmd
-kugelbus.de.		86400	IN	SOA	pu.schlittermann.de. hostmaster.net.schlittermann.de. 18 86400 7200 604800 86400
-kugelbus.de.		86400	IN	RRSIG	MX 7 2 86400 20140621150450 20140522140450 31247 kugelbus.de. MH9jNir2BQVLwnAs92Lks0W3MwsGf6MQqQ15RSGiMfbbgo8IaqgYrBlZ +IcGFuFVX7PI29Y5HtOyVtExKfwGQc2qPKoukFbQ3Ekxcr2+zgvpJZl+ 9U6+S0c78dUSLKsl1Sc1a3P7p2F2fb0nWPx0ZewgT3PmTxZ7OtjOQAaK /bY=
-kugelbus.de.		86400	IN	MX	10 ssl.schlittermann.de.
-kugelbus.de.		86400	IN	RRSIG	SOA 7 2 86400 20140621150450 20140522140450 31247 kugelbus.de. e2vsx6u/peYH0x/NzPE8dR/NHqORM30WWWL1SdRNcYra/Noo4gksv04z WwQXyIVKhQI6C0owgsel0MqD9JvfGMGNedR481ZZLTNiRe/94uLkazbk WCDjPb+1pD7+qGQHetiay+ODOqRDMZCmH+jyC3zHiS5TD6Hn7jQdRnyf hUs=
-kugelbus.de.		86400	IN	NS	hh.schlittermann.de.
-kugelbus.de.		86400	IN	NS	pu.schlittermann.de.
-kugelbus.de.		86400	IN	RRSIG	NS 7 2 86400 20140615074907 20140516074907 31247 kugelbus.de. zuaG0KnQn1cHzg4uqlaRb+JQyN+nRzuETI/mep0EShqOm5m95S9VS3RB lPzZaVYwXkAVycrKfL9Md9eXstofpYdFIHobEfKi1Mp0cgTe6IHqyRyD 6WiCEJ8F9DtBm1kZkbKAcwJLv2BH0lZXS1esa+Zjj17qFDxW7UpUc5jU prk=
-kugelbus.de.		86400	IN	TXT	"invoice: self"
-kugelbus.de.		86400	IN	TXT	"start: 2010-08-02"
-kugelbus.de.		86400	IN	TXT	"utf8: kugelbus.de"
-kugelbus.de.		86400	IN	RRSIG	TXT 7 2 86400 20140615074907 20140516074907 31247 kugelbus.de. qZ0G0EV4ZmxNNEZFvN/6yGqtBrhxHPNFpuqhMLqn+qqHdDZhL+iESH84 rhaoUgqj038pS12qt3rjcGxV1PbBPIFhLz3Gj9oxOi8f9fxahu53V65z sqEOoh67ZuqldBPGjFmUwBDP6BlYYFdaw+jtZxsXB8MTUepbmhWUdCgu Kt4=
-kugelbus.de.		86400	IN	DNSKEY	256 3 7 AwEAAdIZfJL/QFKHxvrZno72yGcqVDa1O815gjhRK8fy5LEHjTDJE2uk 5y1QWFBnW717WGnVgTBZ0xb6rpsNGYwhEKZQOfu7pFg7NimhOFSh6wvN 0v0DObM1ieFgnuHCG/h9SW8Sr1t+K+Fwuccg5psEvX6FEQp25CukOk+Z NCwSll1X
-kugelbus.de.		86400	IN	DNSKEY	257 3 7 AwEAAb4oHp7JRlcdwS5Mqui8PGdgMNWpPZCNJXOQsozIwtI4hznLZgOs 78FMXpaoHrv5BkHSfO41/Q7iq5wVrnCoQvxHS94V4LwcoFfHjVOrug1m by3X2zkNX+8vilh091fN3Ox3lqNO0mvfVzpLkQfWgSJOslxGDdqQmQtH rMfTiQMAUwYLoZz5RfwVl4iiIrzzChBiwtZqXgJZp4ZD9tnBwEXlavjU bv22oQmEawJ0zmvnM3Ynvu/5PQ1BMDgFmHbNCZNdyGKA0K37VUcaxxQ/ Cq9bMh3df8xJifRlJqQnkJqbGn27f+2+vaV1aDeh5ch/5/Nmffr8z+iv iQVBSxMT2e0=
-kugelbus.de.		86400	IN	RRSIG	DNSKEY 7 2 86400 20140615090152 20140516080152 14493 kugelbus.de. QideHWCqOJJE3eKRFoJFkT7GIpxl1bnCSlqXVwvpNCeCyaq8TpQgIIRo Ssoxn1fgb9YonCmw2eXqvAlE7R2fZL7f/aulHx8ZJreOyZGD3HUr95QY PpAckMkWeGba0N4QamKJw0pcqgiBAOb1gcZZBoSnlfB4i2JNQypKKdha 3L2I+CC1xElDZJ4fWbDanDIsQd2HAgRNeGnxciFxzghr3eBVjCuy+YUM VLqyoJLsLayJe5fr+bMu02cIPMMwr6XHPmm7Zvv8xrCQFJi7fzu34Hyp oXcWRmWaEYpUdMtTAqciMsTKkGL2OBT5oad1D4Zdhib7xr/QqA2feijd zDyddg==
-kugelbus.de.		86400	IN	RRSIG	DNSKEY 7 2 86400 20140615090152 20140516080152 31247 kugelbus.de. Zj3yV6cabdIe8QHOTm1bFyogap/Og2Fxk+x9jrIgXAbBnsA1Xkg5+mCZ Xu2KQiAq3rNPmTl88friIvqQ/uJI6MGq+SvwxroEn5mwdCNEvYIoeqUf bB8C21w2SLXILKSGScSgHDxXeQdQm2d+53yB+N5or21OIZnTU6tTyqps +ZE=
-kugelbus.de.		0	IN	NSEC3PARAM 1 0 10 0DDEAD910F3E8BCC238CDAF371F7838482DAFF67
-kugelbus.de.		0	IN	RRSIG	NSEC3PARAM 7 2 0 20140615074907 20140516074907 31247 kugelbus.de. Mt8iczuDi72mCoRz0A+zSs41eSGBVi9mRKaGzPqXVbv0fhtyzv83DBn7 Ls92FtOCPr+P3O1QzgMgxnBWS1sF31tCUghgj1TFmZ7qbQnuSYAOjVzx JZBWsOhWzyedHWq0KJRclu979tPLWwotUH8kBu2FmHC9nBKFeTmp/f4w MOA=
-a.kugelbus.de.		86400	IN	A	192.178.168.222
-a.kugelbus.de.		86400	IN	RRSIG	A 7 3 86400 20140615074907 20140516074907 31247 kugelbus.de. zfUMLhsf8hscpPLcCNg3SGH1DbP4yy4eQxc8EC8yiZski/i4f3pXeHKg M3U0y60rHSvfS0JKy85EkIMQg0csSUp/z78J1JZ7dyKoKJwoiffU8vUO Blpn+YPwrTILsyeyU1u5SyeYyqWVv+9s/6OxXQwgfqOHaeVuWLTUpebt O8Y=
-firma180.kugelbus.de.	86400	IN	MX	10 k180.kugelbus.de.
-firma180.kugelbus.de.	86400	IN	RRSIG	MX 7 3 86400 20140615074907 20140516074907 31247 kugelbus.de. Vaui/f1kz6HubIPypbo/lGI55hwqJWDj9XBzs1y6rowdDx31ia6Jpb27 Y92+W2gQwUEj9Ft/4cZcq3lK0JV9bgMEwL4KxSJbPb0lMAQA9afJ9Y35 +5UT8t05hzZJCFjvtqVjlhGTeKwjJ4WjTN7jVBonWExJuhpgSHVWHW/x MZ4=
-firma181.kugelbus.de.	86400	IN	MX	10 k181.kugelbus.de.
-firma181.kugelbus.de.	86400	IN	RRSIG	MX 7 3 86400 20140615074907 20140516074907 31247 kugelbus.de. xmyeEupCXUv5MqXRKfkAByEfsos0wRwKDMORAsmpkLKI3MBen+8Sz+VG cR5htim8hRWZzztrOT4SwJa7kR0N2Wolpg/Aylj8cOAozaU+iwTTusrE dgYWaP3uuWn8BkH8HsXUrq9XvuC59vWNkmiftDOgNx+y/OlhzSv5scfw r5I=
-firma182.kugelbus.de.	86400	IN	MX	10 k182.kugelbus.de.
-firma182.kugelbus.de.	86400	IN	RRSIG	MX 7 3 86400 20140615074907 20140516074907 31247 kugelbus.de. TDDLPx/rOFDc6FquH+9NGgLxndJ967NbaOPTf24up+MQfbXN/2IBwRKc LGK38eGJNX6SbWkgcvmTgS4bMcd/gUD7P+amaZ/2yOnG81PP7iAb8sYS TLkapOK8Z1Sw/TQkLfVKH3nXWua0ujjoAohVjChjjnNVir0rqW99lmZ2 lI8=
-firma183.kugelbus.de.	86400	IN	MX	10 k183.kugelbus.de.
-firma183.kugelbus.de.	86400	IN	RRSIG	MX 7 3 86400 20140615074907 20140516074907 31247 kugelbus.de. bg0Ag9swRX0FgS8pHI9LIEP03qIZoHvAe5Q3Qai513PPPr3zlPXdj9f3 P0u0UNd7EcBfYODGRIzVyqksCe5gkQ30WbHELQ/d0xwlLUFmXGOfXOl+ kNaYhTqa/CQexFlSIDt+S/o9hXI2LrRQxmVL6Yctbl02NwbZ13zzEuL2 Qg8=
-k180.kugelbus.de.	86400	IN	A	212.80.235.180
-k180.kugelbus.de.	86400	IN	RRSIG	A 7 3 86400 20140615074907 20140516074907 31247 kugelbus.de. D+k+z/5OJ7geyq6NjQF77ZzI1mBjWrX0cJz+ZVNBU3FKENiSHecprRg/ WSb30yjsKwiq0kz65qvBi///ymtf5rYa/6/5d3Px07n3Q6zXDjarEBR7 EPTZldDcbdKYfxpqyNun574tL2Yf8cP9jg4+3IEmQRTDPpBAVhLPr7a/ A4k=
-k181.kugelbus.de.	86400	IN	A	212.80.235.181
-k181.kugelbus.de.	86400	IN	RRSIG	A 7 3 86400 20140615074907 20140516074907 31247 kugelbus.de. e6lWuLkcL7HGCasqKnFijTmOUnk94Ib5JiuUaaFKQvBzyx/jQ6nRo2aq qZEnGn6+cE/cVALusIV6tB6VVh0Vv+MvguX43XehkCr5+d2cAyC2aHuc LISucaBj5Y46v6M/mvnHvKcXWAc2F5Ml4Z5tksHK47deAcvpHZ9Ybe+f t1s=
-k182.kugelbus.de.	86400	IN	A	212.80.235.182
-k182.kugelbus.de.	86400	IN	RRSIG	A 7 3 86400 20140615074907 20140516074907 31247 kugelbus.de. Ufz7b8jU0HeTwiSsWGf3BUso0Dh3l3dEuAUQj5ojCQ7wzePQoQWtw/jZ VTpXkd2ARV/L9W8oYnoxW/2HbTiqAaC4jkJOFEQxaAF3dzuSpdAm0/mI qbRznDd1KZYYVN5pROZNZ+FBI6P764ErUQLUcvR+osdqYrYJm4bz4S69 jF4=
-k183.kugelbus.de.	86400	IN	A	212.80.235.183
-k183.kugelbus.de.	86400	IN	RRSIG	A 7 3 86400 20140615074907 20140516074907 31247 kugelbus.de. iXVgdtt2ZPa/YhrqBa5NcFVwGIr8m7II4UwPgNlBZU2Z94UQm9KVZ359 Bs6/H7IGm9DMZcRMbE3qYjXUS3dc7hjd3/dCBuMd2tm9aEiFA1A0daAs +c2nOq6HSMyxbrskByMZzVSAmyIyHmVi/hIsskYwTTO+fdI1nSfCeDNB +PY=
-rp.kugelbus.de.		3600	IN	RRSIG	AAAA 7 3 3600 20140620114226 20140521104226 31247 kugelbus.de. bjETOc6PAR141lLJ9ASX1TAtktclScMhTSsTG4vVveF4GVLmWSAXioTv DQv7sL7BlymKYEPC5iofpqqQkViDv9a+JS9ZRLVL0gHDbmifAjQj/64L TPdoSM7qggTlbkTpdwx1xP7dnoX3y+8ji4mqWlk19+jyEojKI3nXk4ZJ M98=
-rp.kugelbus.de.		3600	IN	AAAA	2a01:1e8:e100:847c::1
-www.kugelbus.de.	86400	IN	A	212.80.235.150
-www.kugelbus.de.	86400	IN	RRSIG	A 7 3 86400 20140615074907 20140516074907 31247 kugelbus.de. IiBFYhBBRdTsH3PbKuL37EweOtctmxPMB9quMYkRkk/Vok2E+hRhv/Rl ZyiHE/kiiFSVreUc4L6ZN7ZZhpuNOVGakXKMiRDTd/pLbs9b28PgwEge 6TeSUdKNSlOS2TkbJLEUdXIP8iRmxRfjc7ISavg3dCPMOBXGUSno3UZw azI=
-0R9CKH4HK453VFREKG89VSMUV2FDN3SA.kugelbus.de. 86400 IN NSEC3 1 0 10 0DDEAD910F3E8BCC238CDAF371F7838482DAFF67 0U6GJVGAK0B95KBBUHB8R8P6HTL3Q0GH A RRSIG
-0R9CKH4HK453VFREKG89VSMUV2FDN3SA.kugelbus.de. 86400 IN RRSIG NSEC3 7 3 86400 20140615074907 20140516074907 31247 kugelbus.de. BJshX3u76wb7oJG2heXfljEIFrQQhqX4zhEqFQXiHeLA1GF9xl8v3b7w mGs3O/dnFWjzCy7Qy+zs59lE+0yvWlrnzdZzpLUWcJUsfZaTDTZSIU2u pEECtVAYl0eIopWERVs2nOAgDIStbxB/qcmAxtlhp8AfMwkKjTDQJnHp DYs=
-0U6GJVGAK0B95KBBUHB8R8P6HTL3Q0GH.kugelbus.de. 86400 IN NSEC3 1 0 10 0DDEAD910F3E8BCC238CDAF371F7838482DAFF67 2593VCBJBL3VTVHN2IK23CCIRUCGLEAA MX RRSIG
-0U6GJVGAK0B95KBBUHB8R8P6HTL3Q0GH.kugelbus.de. 86400 IN RRSIG NSEC3 7 3 86400 20140615074907 20140516074907 31247 kugelbus.de. wH3ECYBc8KHTfdE/lLCtYUQYrZ2eGqwTxJbZCkPLuVQ7WVuFGS7XfKT0 yBdaOesJdBIFNKRSM0uDh0mnxwaLDx8GY2jP4EMTzm6FXN9CFs00Nscm MrgyV+0ZrSvu8VCj/sbsXra9GvtrcgU9tM3L5nK+2p76oiPzglnqxoXn kDs=
-2593VCBJBL3VTVHN2IK23CCIRUCGLEAA.kugelbus.de. 86400 IN NSEC3 1 0 10 0DDEAD910F3E8BCC238CDAF371F7838482DAFF67 2DM84U3H3AA2VNMU33OIKA1QG7Q3TQHV A RRSIG
-2593VCBJBL3VTVHN2IK23CCIRUCGLEAA.kugelbus.de. 86400 IN RRSIG NSEC3 7 3 86400 20140615074907 20140516074907 31247 kugelbus.de. Pq3uZBOYVNmJrgkkDN1FsNwiMWtVTroUtA6m1zAxZGUU6kpTLdvhrdC8 X9h6WzeyR9Jbm83WNMnKxiSXq6vbYSOU9LQVnpJN9wREVqxqwwIJSgcX MuowjgjWmfjU7NH3RFR7YxPo4MUoAOanYXpSQy0GKd7dFPCbIfMj9U4U BFw=
-2DM84U3H3AA2VNMU33OIKA1QG7Q3TQHV.kugelbus.de. 86400 IN NSEC3 1 0 10 0DDEAD910F3E8BCC238CDAF371F7838482DAFF67 2TPQK9E8RVRMD8PQUDV9KNAHA4HQKBDN A RRSIG
-2DM84U3H3AA2VNMU33OIKA1QG7Q3TQHV.kugelbus.de. 86400 IN RRSIG NSEC3 7 3 86400 20140620114118 20140521104118 31247 kugelbus.de. cHJ43Qircpo71H+hPGFkXfNwa+C0R49tLJFoB1UVn9KGzl/X3yv88IVA Th4+nJMz2eSgCx80EXGr+XDxqDwwVYsRxmirg6eLqGyIYxzmuRYSFqfJ aNPeCPgS6eMgUj+5wIYOmtmvFaO/rYqzlZ+xiK5mLF73npFL9HsADSkR DjA=
-2TPQK9E8RVRMD8PQUDV9KNAHA4HQKBDN.kugelbus.de. 86400 IN NSEC3 1 0 10 0DDEAD910F3E8BCC238CDAF371F7838482DAFF67 8H88OTVRBHS3LE691SGLBI1MDR3HNCL3 MX RRSIG
-2TPQK9E8RVRMD8PQUDV9KNAHA4HQKBDN.kugelbus.de. 86400 IN RRSIG NSEC3 7 3 86400 20140615074907 20140516074907 31247 kugelbus.de. BtwkglyaKHGJM2YacX1dZAGhrQkG/5zpziK9JUErTfSJ+UHQCaFGdZX+ uhKIjgUWH5Np0rd7MtDEBvtewSX+tw8B+bYmZqGQtJkEdi44Vk40B5yk mchb0s7wfL0B5zDJcSwcHIvsXxGFMr4jyl0JOaOQ7Tp0bq+dAOqjm+Hl Phc=
-8H88OTVRBHS3LE691SGLBI1MDR3HNCL3.kugelbus.de. 86400 IN NSEC3 1 0 10 0DDEAD910F3E8BCC238CDAF371F7838482DAFF67 BOS537U20E73QOBE3N4QOHPHB4BPK192 MX RRSIG
-8H88OTVRBHS3LE691SGLBI1MDR3HNCL3.kugelbus.de. 86400 IN RRSIG NSEC3 7 3 86400 20140615074907 20140516074907 31247 kugelbus.de. JMc1AFtP3c+Od9TNS/d8P+lpkHQG/LnKrJAGi6IwZPiMXi+COTExUHUl E7+gBz5owogv9LwIfIFpulUMAjpx9XaCQF36qb1ke54ceKHV+zjhQZEs s8MGjwsxjLy65oN2tBfoWx07jiWLAYKUFpiFWjLuZIzDMw4trgWkn9QR jY8=
-BOS537U20E73QOBE3N4QOHPHB4BPK192.kugelbus.de. 86400 IN NSEC3 1 0 10 0DDEAD910F3E8BCC238CDAF371F7838482DAFF67 D8IBS9FUE7TQPC73J8LQD0NAKUU9NTL9 A RRSIG
-BOS537U20E73QOBE3N4QOHPHB4BPK192.kugelbus.de. 86400 IN RRSIG NSEC3 7 3 86400 20140618211808 20140519201808 31247 kugelbus.de. e1AkRwzd5FxcX23zD/wiC2dBOzXGGz4f54VfbjfazQaVy84gRSl7L7K4 I1zIkoE+DYeW9URhsEoiXQgjzmlG6GhSwwSLaOdbKyFLO5cY+u9sWoAW rnupf6/HzyLkqeC+OGdKq9mkZ2j+bU3oQgllKr3KphnxCp49BcKaswhE I+g=
-D8IBS9FUE7TQPC73J8LQD0NAKUU9NTL9.kugelbus.de. 86400 IN NSEC3 1 0 10 0DDEAD910F3E8BCC238CDAF371F7838482DAFF67 ELVRHMFILU1ER47ON682O2E7Q1HTA6T6 NS SOA MX TXT RRSIG DNSKEY NSEC3PARAM
-D8IBS9FUE7TQPC73J8LQD0NAKUU9NTL9.kugelbus.de. 86400 IN RRSIG NSEC3 7 3 86400 20140620114237 20140521104237 31247 kugelbus.de. lgRK+kouaMP6M+LhTgYkrDczfMQeUQiph85mb/45Wl/MRjw/E8bipLeI hMecImUz+Iusf0wJZ0zqNxS8sMMTQKxIfWtEkwjrkq/rF9x+izk+FIxj XhF6dOl3rbr6haUeRRY/GEIykPw4dFp39K2/usteoSyXEv/XDQ586Yxj kwA=
-ELVRHMFILU1ER47ON682O2E7Q1HTA6T6.kugelbus.de. 86400 IN RRSIG NSEC3 7 3 86400 20140620114226 20140521104226 31247 kugelbus.de. fq9Azb1gDrtyDo2bbh0SURvc4V9AlgFb08BPAQXAQjhABipLYq/7NupJ 0xGeQYGdQasAxNXvRPflRhdd6iwiAZrBDIOPxjAvZ4I5iRRFKu5m0n6R 8NXay50ymMbEPHASmoN7y78XxJqZIxlusfclv6hlTCaJeYABo1QnuZwg 4N4=
-ELVRHMFILU1ER47ON682O2E7Q1HTA6T6.kugelbus.de. 86400 IN NSEC3 1 0 10 0DDEAD910F3E8BCC238CDAF371F7838482DAFF67 NI0SJC95TMP2E2PF58A2460KK7LUD3VO AAAA RRSIG
-NI0SJC95TMP2E2PF58A2460KK7LUD3VO.kugelbus.de. 86400 IN NSEC3 1 0 10 0DDEAD910F3E8BCC238CDAF371F7838482DAFF67 R4SPOIPJ3LVFG96IPUEFH9SRARP9VV31 A RRSIG
-NI0SJC95TMP2E2PF58A2460KK7LUD3VO.kugelbus.de. 86400 IN RRSIG NSEC3 7 3 86400 20140618212211 20140519202211 31247 kugelbus.de. SBTnTWJ7OHxNm96xz9w5vDn4VEW8IejMCJUeox0Zk7CGfEErxVyFc4a7 ek0lkPi2p90c+Exh7zN0X9tHD6OfGSjCkMtdUERn+7OG7HIsTAwWJiwj Za/wj6rrZJ2rSPnDH9sNyMSSh4Sl9wtkTwZ4WCdRvUtUfwrXlIMO/YNK c5Q=
-R4SPOIPJ3LVFG96IPUEFH9SRARP9VV31.kugelbus.de. 86400 IN NSEC3 1 0 10 0DDEAD910F3E8BCC238CDAF371F7838482DAFF67 RMC55B74CLBU1C4I8I3NBFLM3OU5VVT2 A RRSIG
-R4SPOIPJ3LVFG96IPUEFH9SRARP9VV31.kugelbus.de. 86400 IN RRSIG NSEC3 7 3 86400 20140615074907 20140516074907 31247 kugelbus.de. jjr1yN9BTOSc5qWTfkO2JBGPEoQskcHGpgIfoqCeyaK/w+yf467AAB0n sZgmRcGve42LwZUwbe+GhCBr/QGgKEsMqNZYtSPcivrIhdySVkBxcoSS OIBTXiE0nYufgxcEuVt6n8lWoUq6kep6xZ/lxfcPpIyAFqL/QlWqv+q0 lVw=
-RMC55B74CLBU1C4I8I3NBFLM3OU5VVT2.kugelbus.de. 86400 IN NSEC3 1 0 10 0DDEAD910F3E8BCC238CDAF371F7838482DAFF67 0R9CKH4HK453VFREKG89VSMUV2FDN3SA MX RRSIG
-RMC55B74CLBU1C4I8I3NBFLM3OU5VVT2.kugelbus.de. 86400 IN RRSIG NSEC3 7 3 86400 20140615090338 20140516080338 31247 kugelbus.de. OUIDj0k1SXx1ua8SS3vKGJfojnCcTS4dcYnyuFfBxWD7N+Lbiwp4BuNI I8Z5V0IYCQy6x/rBcpiqJF11PTPHxtAk3gehB+Yu2KechP7n3UIcXFn0 LMNMcvjGa7Fa4ntv/zBWZZgMmbCsa3Jxjx8VnhXdsmLsMeoyvvODy164 BXo=
-kugelbus.de.		86400	IN	SOA	pu.schlittermann.de. hostmaster.net.schlittermann.de. 18 86400 7200 604800 86400
-heiko.			0	ANY	TSIG	hmac-md5.sig-alg.reg.int. 1400790918 300 16 Ithy5I1QiLQHkWU7i9GqXA== 49003 NOERROR 0 
-;; Query time: 51 msec
-;; SERVER: 84.19.194.5#53(84.19.194.5)
-;; WHEN: Thu May 22 22:35:18 2014
-;; XFR size: 64 records (messages 1, bytes 7506)
-
--- a/t/samples/b	Thu Jul 14 10:30:58 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-$ORIGIN km21.de.
-$TTL 1d
-; do NOT EDIT the SOA records SERIAL number!
-@               SOA    pu.schlittermann.de. hostmaster.schlittermann.de.  (
-		1397766411  ; serial
-		86400	    ; refresh
-		7200	    ; retry
-		604800	    ; expire
-		300	    ; min ttl
-		)
-                NS     hh.schlittermann.de.
-                NS     pu.schlittermann.de.
-                TXT    "invoice: self"
-                TXT    "utf8: km21.de"
-                TXT    "start: 1396981300 2014-04-08T20:21:40"
-tte             A      85.214.245.1
-foo		CNAME	tte
-bar		CNAME	tte	; 
-; do not remove the trailing spaces from the next line!
-baz		CNAME	tte	 
-faz		CNAME	a.b.c.  ;
--- a/t/samples/c	Thu Jul 14 10:30:58 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-$ORIGIN km21.de.
-$TTL 1d
-; do NOT EDIT the SOA records SERIAL number!
-@               SOA    pu.schlittermann.de. hostmaster.schlittermann.de. 1397766411 86400 7200 604800 300
-                NS     hh.schlittermann.de.
-                NS     pu.schlittermann.de.
-                TXT    "invoice: self"
-                TXT    "utf8: km21.de"
-                TXT    "start: 1396981300 2014-04-08T20:21:40"
-tte             A      85.214.245.1
-    IN A 1.1.1.1
-    TXT "tte"
-; only one space
- IN TXT "tte2"
- IN MX 10 mexico.
-  IN MX 20 mx20.
--- a/t/samples/d	Thu Jul 14 10:30:58 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-$ORIGIN km21.de.
-$TTL 1d
-; do NOT EDIT the SOA records SERIAL number!
-@               SOA    pu.schlittermann.de. hostmaster.schlittermann.de. 1397766411 86400 7200 604800 300
-                NS     hh.schlittermann.de.
-                NS     pu.schlittermann.de.
-                TXT    "invoice: self"
-                TXT    "utf8: km21.de"
-                TXT    "start: 1396981300 2014-04-08T20:21:40"
-tte             A      85.214.245.1
-    IN A 1.1.1.1
-    TXT "tte"
-; only one space
- IN TXT "tte2"
- IN MX 10 mexico.
-  IN MX 20 mx20.
-foo  A 1.1.1.2
-bar.km21.de. A 1.1.1.3
-abc.de A 1.2.3.4
--- a/t/samples/frey-1	Thu Jul 14 10:30:58 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-$TTL 5m
-$ORIGIN example.com.
-@	SOA p hostmaster (
-	47
-	1h
-	15m
-	7d
-	5m
-	)
-
-	NS  p
-p	A   1.1.1.1
-p	A   2.2.2.2
-
-proxy.mm.frey     CNAME	uxa.frey
-portal.mm.frey    CNAME	uxb.frey
--- a/t/samples/frey-2	Thu Jul 14 10:30:58 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,15 +0,0 @@
-$TTL 5m
-$ORIGIN example.com.
-@	SOA p hostmaster (
-	47
-	1h
-	15m
-	7d
-	5m
-	)
-
-	NS  p
-p	A   1.1.1.1
-
-uxa.frey    CNAME   proxy.mm.frey  
-uxb.frey    CNAME   portal.mm.frey