DNS-ZoneParse
view release on metacpan or search on metacpan
lib/DNS/ZoneParse.pm view on Meta::CPAN
}
$r = $ttl{'W'} * 7;
$r = ( $r + $ttl{'D'} ) * 24;
$r = ( $r + $ttl{'H'} ) * 60;
$r = ( $r + $ttl{'M'} ) * 60;
$r = ( $r + $ttl{'S'} );
die unless $r == $ttl{'S'} + 60 * ( $ttl{'M'} + 60 * ( $ttl{'H'} + 24 * ( $ttl{'D'} + 7 * $ttl{'W'} ) ) );
return $r;
}
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Private Methods
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
sub _initialize {
my $self = shift;
$dns_id{$self} = {};
$dns_soa{$self} = {};
$dns_ns{$self} = [];
$dns_a{$self} = [];
$dns_cname{$self} = [];
$dns_mx{$self} = [];
$dns_txt{$self} = [];
$dns_ptr{$self} = [];
$dns_a4{$self} = [];
$dns_srv{$self} = [];
$dns_hinfo{$self} = [];
$dns_rp{$self} = [];
$dns_loc{$self} = [];
$dns_generate{$self} = [];
$dns_last_name{$self} = undef;
$dns_last_origin{$self} = undef;
$dns_last_ttl{$self} = undef;
$dns_last_class{$self} = 'IN'; # Class defaults to IN.
$dns_found_origins{$self} = {};
$last_parse_error_count{$self} = 0;
return 1;
}
sub _load_file {
my ( $self, $zonefile, $origin ) = @_;
my $zone_contents;
if ( ref( $zonefile ) eq 'SCALAR' ) {
$zone_contents = $$zonefile;
} else {
my $inZONE;
if ( open( $inZONE, '<', $zonefile ) ) {
local $/;
$zone_contents = <$inZONE>;
close( $inZONE );
} else {
croak qq[DNS::ZoneParse Could not open input file: "$zonefile":$!];
}
}
if ( $self->_parse( $zonefile, $zone_contents, $origin ) ) { return 1; }
}
sub _parse {
# Support IsAlnum for unicode names.
use utf8;
my ( $self, $zonefile, $contents, $origin ) = @_;
$self->_initialize();
# Here's how we auto-detect the zonefile and origin. Note, the zonefile is
# only used to print out a comment in the file, so its okay if we're
# inaccurate. First, prefer what the user configures. Next, try to read a
# comment we would have written if we wrote the file out in the past.
# Finally, pick up any SOA or $ORIGIN statements present in the file.
if ( ref( $zonefile ) eq 'SCALAR' ) { $zonefile = ''; }
if ( !$origin || !$zonefile ) {
# I don't know why the ( dns)? capture is there, perhaps at one point
# this module wrote a different header comment? I'll leave it as to
# preserve whatever backwards compatability this affords us...
$contents =~ /^\s*;\s*Database file (\S+)( dns)? for (\S+) zone/im;
if ( !$origin && $3 ) { $origin = $3; }
if ( !$zonefile && $1 ) { $zonefile = $1; }
}
if ( $zonefile ) {
$zonefile = basename( $zonefile );
} else {
$zonefile = 'unknown';
}
if ( $origin ) {
# A trite way of insuring there is a trailing dot on the origin. It's
# really important you supply a trailing . in an origin when you mean
# it.
$origin =~ s/([^.])$/$1./;
} else {
$origin = '';
}
$dns_id{$self} = {
ZoneFile => $zonefile,
Origin => $origin,
};
my $records = $self->_clean_records( $contents );
# Everything valid in the name, except the '.' character.
my $valid_name_start_char = q/(?:[\p{IsAlnum}\@_\-*:+=!#$%^&`~,\[\]{}|?'\/]|/
. join( '|', map { "\\\\$_" } @ESCAPABLE_CHARACTERS ) . ')';
# The above, but adds the literal '.' character.
my $valid_name_char = qr/(?:$valid_name_start_char|[\.\\])/o;
my $valid_txt_char = qr/\S+/o;
my $valid_quoted_txt_char = qr/.+/o;
# Like the above, but adds whitespace (space and tabs) too.
my $valid_quoted_name_char = qr/(?:$valid_name_start_char|[. ;\t()\\])/o;
my $valid_name = qr/$valid_name_start_char$valid_name_char*/o;
my $valid_ip6 = qr/[\@a-zA-Z_\-\.0-9\*:]+/;
my $rr_type = qr/\b(?:NS|A|CNAME)\b/i;
#my $ttl_cls = qr/(?:($rr_ttl)\s)?(?:($rr_class)\s)?/o;
my $ttl_cls = qr/(?:\b((?:$rr_ttl)|(?:$rr_class))\s)?(?:\b((?:$rr_class)|(?:$rr_ttl))\s)?/o;
my $generate_range = qr{\d+\-\d+(?:/\d+)?};
my $last_good_line;
( run in 1.645 second using v1.01-cache-2.11-cpan-99c4e6809bf )