#!/usr/local/bin/perl -w
######################################################################
#
# DNS/Zone.pm
#
# $Id: Zone.pm,v 1.7 2003/02/04 15:22:12 awolf Exp $
# $Revision: 1.7 $
# $Author: awolf $
# $Date: 2003/02/04 15:22:12 $
#
# Copyright (C)2001-2003 Andy Wolf. All rights reserved.
#
# This library is free software; you can redistribute it and/or
# modify it under the same terms as Perl itself.
#
######################################################################
package DNS::Zone;
no warnings 'portable';
use 5.6.0;
use strict;
use warnings;
use vars qw($AUTOLOAD);
my $VERSION = '0.85';
my $REVISION = sprintf("%d.%02d", q$Revision: 1.7 $ =~ /(\d+)\.(\d+)/);
sub new {
my($pkg, $name) = @_;
my $class = ref($pkg) || $pkg;
my $self = {
'_ID' => undef,
'NAME' => $name,
'LABELS' => [],
};
bless $self, $class;
return $self;
}
# The id shall only be used to search if
# the backend allows to use ids more
# efficiently. Setting this attribute
# should only be done when reading/writing
# from/to the backend (e.g. database)
########################################
sub id {
my($self, $id) = @_;
$self->{'_ID'} = $id if($id);
return($self->{'_ID'});
}
sub name {
my($self, $name) = @_;
$self->{'NAME'} = $name if($name);
return($self->{'NAME'});
}
#May be used to store a reference to some super
#object like a master server.
sub master {
my($self, $ref) = @_;
$self->{'MASTER'} = $ref if($ref);
return $self->{'MASTER'};
}
sub add {
my($self, $label) = @_;
push @{ $self->{'LABELS'} }, ($label);
return $label;
}
sub delete {
my($self, $record) = @_;
my $found = 0;
foreach my $label ($self->labels()) {
my @array = $label->records();
for (my $i=0 ; $array[$i] ; $i++) {
if($array[$i] == $record) {
$found = 1;
splice @array, $i, 1;
}
}
$label->records(@array);
}
return $found ? $self : undef;
}
sub label {
my($self, $ref) = @_;
my $label;
if(exists $ref->{'NAME'} && $ref->{'NAME'}) {
for ($self->labels()) {
$label = $_ if($_->label() eq $ref->{'NAME'});
}
}
elsif(exists $ref->{'ID'} && $ref->{'ID'}) {
for ($self->labels()) {
$label = $_ if($_->id() eq $ref->{'ID'});
}
}
return $label;
}
sub labels {
my($self, @labels) = @_;
$self->{'LABELS'} = \@labels if(scalar @labels);
my @result = @{ $self->{'LABELS'} } if(ref($self->{'LABELS'}) eq 'ARRAY');
return @result;
}
sub sort {
my($self) = @_;
my @result = sort {
my(@a) = reverse split /\./, $a->label();
my(@b) = reverse split /\./, $b->label();
for(my $i=0 ; $a[$i] || $b[$i] ; $i++) {
if($a[$i] && $b[$i]) {
return ($a[$i] cmp $b[$i]) if($a[$i] cmp $b[$i]);
}
elsif($a[$i] && !$b[$i]) {
return 1;
}
elsif(!$a[$i] && $b[$i]) {
return -1;
}
else {
return 0;
}
}
return 0;
} $self->labels();
$self->labels(@result);
return $self;
}
sub dump {
my($self) = @_;
my %ttl_hash;
my $labellength = 0;
for my $label ($self->sort()->labels()) {
my $length = length $label->label();
$labellength = $length if($length > $labellength);
my @records = $label->records();
for (@records) {
my $ttl = $_->ttl();
if(exists $ttl_hash{$ttl}) {
$ttl_hash{$ttl} += 1;
}
else {
$ttl_hash{$ttl} = 1;
}
}
}
my $ttl_default = 0;
my $ttl_max = 0;
for (keys %ttl_hash) {
$ttl_default = $_ if($ttl_hash{$_} > $ttl_max);
}
my $origin = $self->name();
print '$TTL ', "$ttl_default\n";
print '$ORIGIN ', "$origin\.\n";
foreach my $label ($self->labels()) {
print "\n";
$label->dump("%-" . $labellength . "s", $origin, $ttl_default);
}
return $self;
}
sub toXML {
my($self) = @_;
my $result;
$result .= qq(\n);
$result .= qq(\n) . $self->name() . qq(\n);
map { $result .= $_->toXML() } $self->labels();
$result .= qq(\n);
return $result;
}
sub debug {
my($self) = @_;
eval {
use Data::Dumper;
print Dumper($self);
};
return $self;
}
1;
__END__
=pod
=head1 NAME
Bind::Zone - DNS Zone
=head1 SYNOPSIS
use DNS::Zone;
my $zone = new DNS::Zone($zone_name_string);
$zone->sort();
$zone->dump();
$zone->debug();
=head1 ABSTRACT
This class represents a zone in the domain name service (DNS).
=head1 DESCRIPTION
A zone has a name and can contain labels. You can dump() the
zone use a standard format and you can use debug() to get an
output from Data::Dumper that shows the object in detail
including all referenced objects.
=head1 AUTHOR
Copyright (C)2001-2003 Andy Wolf. All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
Please address bug reports and comments to:
zonemaster@users.sourceforge.net
=head1 SEE ALSO
L, L, L
=cut