05364d326b
git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/trunk@8888 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd
1596 lines
43 KiB
Perl
Executable File
1596 lines
43 KiB
Perl
Executable File
#!/usr/bin/perl
|
|
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
|
#This is ported forward from xCAT 1.3
|
|
#TODO: A lot of stuff was handled by the script portion of makedns, notably:
|
|
# db.cache
|
|
# forwarders
|
|
# chroot
|
|
# dnsallowq
|
|
# mucking with sysconfig
|
|
package xCAT_plugin::bind;
|
|
use strict;
|
|
no strict "refs"; #This code is as yet still very broken...
|
|
|
|
#use warnings;
|
|
use Sys::Hostname;
|
|
use Cwd;
|
|
use Getopt::Long;
|
|
use xCAT::Table;
|
|
use xCAT::MsgUtils;
|
|
use Data::Dumper;
|
|
|
|
sub handled_commands
|
|
{
|
|
return {"makedns" => "bind"};
|
|
}
|
|
|
|
#NAME
|
|
#
|
|
# h2n - Translate host table to name server file format
|
|
# $Date: 1999/08/08 17:17:56 $ $Revision: 8.2 $
|
|
#
|
|
#SYNOPSIS
|
|
#
|
|
# h2n -d DOMAIN -n NET [options]
|
|
|
|
# Various defaults
|
|
my $Host;
|
|
my $doaliases = 1;
|
|
my $domx = 1;
|
|
my $dowks = 0;
|
|
my $dotxt = 0;
|
|
my $dontdodomains = 0;
|
|
my $Bootfile = "/etc/named.conf";
|
|
my $DBDir = "/var/named/";
|
|
my $Domain = "";
|
|
my $Hostfile = "/etc/hosts";
|
|
my $Commentfile = "";
|
|
my $Commentfileread = 0;
|
|
my $User = "root";
|
|
my $RespHost = "";
|
|
my $RespUser = "";
|
|
my $DefSerial = 1;
|
|
my $DefRefresh = 10800;
|
|
my $DefRetry = 3600;
|
|
my $DefExpire = 604800;
|
|
my $DefTtl = 86400;
|
|
my $UseDefSOAValues = 0;
|
|
my $DefMxWeight = 10;
|
|
my $Defsubnetmask = "";
|
|
my $ForceSerial = -1;
|
|
my $UseDateInSerial = 1;
|
|
my $DateSerial = 0;
|
|
my $Version = 8;
|
|
my $request;
|
|
my $callback;
|
|
my @forwarders;
|
|
|
|
#Declarations to alleviate use strict, since the code doesn't seem to be structured well enough to avoid it for these cases
|
|
my $Bootsecsaveaddr;
|
|
my $Bootsecaddr;
|
|
my @Networks;
|
|
my @bootmsgs_v4;
|
|
my @bootmsgs_v8;
|
|
my @elimpats;
|
|
my @cpats;
|
|
my @makesoa;
|
|
my $Domainfile;
|
|
my %cpatrel;
|
|
my @Servers;
|
|
my $Serial;
|
|
my $Refresh;
|
|
my @Mx;
|
|
my $Expire;
|
|
my %Hosts;
|
|
my %Comments;
|
|
my $Domainpattern;
|
|
my @Netpatterns;
|
|
my $Ttl;
|
|
my $Retry;
|
|
my %Cnames;
|
|
my %CommentRRs;
|
|
my $soa_warned;
|
|
my %Aliases;
|
|
my %Netfiles;
|
|
|
|
sub process_request
|
|
{
|
|
$request = shift;
|
|
$callback = shift;
|
|
%Netfiles = ();
|
|
%Aliases = ();
|
|
$soa_warned = 0;
|
|
my $canonical;
|
|
my $aliases;
|
|
%Comments = ();
|
|
%CommentRRs = ();
|
|
%Cnames = ();
|
|
%Hosts = ();
|
|
@Netpatterns = ();
|
|
$DBDir = "/var/named/";
|
|
|
|
unless (-d $DBDir)
|
|
{
|
|
$DBDir = "/var/lib/named/";
|
|
}
|
|
|
|
# if both do not exist, make /var/named
|
|
unless (-d $DBDir)
|
|
{
|
|
$DBDir = "/var/named/";
|
|
my $cmd = "/bin/mkdir $DBDir";
|
|
my $outref = xCAT::Utils->runcmd("$cmd", 0);
|
|
if ($::RUNCMD_RC != 0)
|
|
{
|
|
my $rsp = {};
|
|
$rsp->{data}->[0] = "Could not create $DBDir.\n";
|
|
xCAT::MsgUtils->message("E", $rsp, $callback, 1);
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
$Host = hostname;
|
|
$Host =~ s/\..*//;
|
|
my $sitetab = xCAT::Table->new('site');
|
|
unless ($sitetab)
|
|
{
|
|
my $rsp = {};
|
|
$rsp->{data}->[0] = "No site table found.\n";
|
|
xCAT::MsgUtils->message("E", $rsp, $callback, 1);
|
|
return;
|
|
}
|
|
my @args = ();
|
|
if ($request->{arg})
|
|
{
|
|
@args = @{$request->{arg}};
|
|
@ARGV = @{$request->{arg}};
|
|
}
|
|
&checkusageandversion($callback);
|
|
|
|
(my $fent) = $sitetab->getAttribs({key => 'forwarders'}, 'value');
|
|
if ($fent and defined $fent->{value})
|
|
{
|
|
@forwarders = split /[,:;]/, $fent->{value};
|
|
}
|
|
unless (grep /^-d$/, @args)
|
|
{
|
|
(my $dent) = $sitetab->getAttribs({key => 'domain'}, 'value');
|
|
if ($dent and $dent->{value})
|
|
{
|
|
push @args, "-d";
|
|
$dent->{value} =~ s/\.$//;
|
|
push @args, $dent->{value};
|
|
}
|
|
}
|
|
unless (grep /^-s$/, @args)
|
|
{
|
|
push @args, "-s";
|
|
push @args, $Host;
|
|
}
|
|
unless (grep /^-n$/, @args)
|
|
{
|
|
my $nettab = xCAT::Table->new('networks');
|
|
unless ($nettab)
|
|
{
|
|
my $rsp = {};
|
|
$rsp->{data}->[0] =
|
|
"Unable to open networks table, has makenetworks been run?.\n";
|
|
xCAT::MsgUtils->message("E", $rsp, $callback, 1);
|
|
return;
|
|
}
|
|
foreach (@{$nettab->getAllEntries()})
|
|
{
|
|
if ($_->{net} =~ /:/) {
|
|
my $rsp = {};
|
|
$rsp->{data}->[0] = "Ignoring IPv6 network, not supported in bind.pm (site.dnshandler=ddns if you want to do IPv6 DNS records";
|
|
xCAT::MsgUtils->message("W",$rsp,$callback,1);
|
|
next;
|
|
}
|
|
push @args, "-n";
|
|
push @args, $_->{net} . ":" . $_->{mask};
|
|
}
|
|
}
|
|
|
|
push(@bootmsgs_v4, "primary\t0.0.127.IN-ADDR.ARPA db.127.0.0\n");
|
|
push(@bootmsgs_v8,
|
|
qq|zone "0.0.127.IN-ADDR.ARPA" in {\n\ttype master;\n\tfile "db.127.0.0";\n\tnotify no;\n};\n\n|
|
|
);
|
|
|
|
&PARSEARGS($callback, @args);
|
|
&FIXUP($callback);
|
|
unless (open(HOSTS, $Hostfile))
|
|
{
|
|
my $rsp = {};
|
|
$rsp->{data}->[0] = "Unable to open $Hostfile\n";
|
|
xCAT::MsgUtils->message("E", $rsp, $callback, 1);
|
|
exit 1;
|
|
}
|
|
my $data;
|
|
my $comment;
|
|
my $addr;
|
|
my $names;
|
|
LINE: while (<HOSTS>)
|
|
{
|
|
next if /^[ \t]*#/; # skip comment lines
|
|
next if /^$/; # skip empty lines
|
|
chop; # remove the trailing newline
|
|
tr/A-Z/a-z/; # translate to lower case
|
|
|
|
($data, $comment) = split('#', $_, 2);
|
|
($addr, $names) = split(/[ ]+/, $data, 2);
|
|
if ($names =~ /^[ \t]*$/)
|
|
{
|
|
|
|
#$callback->({data=>["Bad line in hosts file ignored '$_'"]});
|
|
next LINE;
|
|
}
|
|
$addr =~ s/^[ ]*//;
|
|
$addr =~ s/[ ]*$//;
|
|
if ($addr !~ /^\d+\.\d+\.\d+\.\d+$/)
|
|
{
|
|
my $rsp = {};
|
|
$rsp->{data}->[0] = "Ignoring $addr (not a valid IPv4 address).\n";
|
|
xCAT::MsgUtils->message("I", $rsp, $callback);
|
|
next LINE;
|
|
}
|
|
|
|
# Match -e args
|
|
my $netpat;
|
|
foreach $netpat (@elimpats)
|
|
{
|
|
next LINE if (/[.\s]$netpat/);
|
|
}
|
|
|
|
# Process -c args
|
|
foreach $netpat (@cpats)
|
|
{
|
|
if (/\.$netpat/)
|
|
{
|
|
($canonical, $aliases) = split(' ', $names, 2);
|
|
$canonical =~ s/\.$netpat//;
|
|
#If we feed in names with, say, underscores, bind complains usually due to default check-names behavior. Later, we may should support putting check-names to ignore, but for now let them know it won't work and skip it
|
|
unless ($canonical =~ /^[a-z0-9-]+$/i) {
|
|
xCAT::MsgUtils->message("E", {errorcode=>[1],error=>["$canonical contains invalid characters, skipping entry"]}, $callback, 1);
|
|
next LINE;
|
|
}
|
|
if ($Cnames{$canonical} != 1)
|
|
{
|
|
printf DOMAIN "%-20s IN CNAME %s.%s.\n", $canonical,
|
|
$canonical, $cpatrel{$netpat};
|
|
$Cnames{$canonical} = 1;
|
|
}
|
|
next LINE;
|
|
}
|
|
}
|
|
|
|
# Check that the address is in the address list.
|
|
my $match = 'none';
|
|
foreach $netpat (@Netpatterns)
|
|
{
|
|
$match = $netpat, last
|
|
if ($addr =~ /^$netpat\./ or $addr =~ /^$netpat$/);
|
|
}
|
|
next if ($match eq 'none');
|
|
|
|
($canonical, $aliases) = split(' ', $names, 2); # separate out aliases
|
|
next if ($dontdodomains && $canonical =~ /\./); # skip domain names
|
|
$canonical =~ s/$Domainpattern//; # strip off domain if there is one
|
|
unless ($canonical =~ /^[a-z0-9-]+$/i) {
|
|
xCAT::MsgUtils->message("E", {errorcode=>[1],error=>["$canonical contains invalid characters, skipping entry"]}, $callback, 1);
|
|
next;
|
|
}
|
|
$Hosts{$canonical} .= $addr . " "; # index addresses by canonical name
|
|
$Aliases{$addr} .= $aliases . " "; # index aliases by address
|
|
$Comments{"$canonical-$addr"} = $comment;
|
|
|
|
# Print PTR records
|
|
my $file = $Netfiles{$match};
|
|
printf $file "%-30s\tIN PTR %s.%s.\n", &REVERSE($addr), $canonical,
|
|
$Domain;
|
|
}
|
|
|
|
#
|
|
# Go through the list of canonical names.
|
|
# If there is more than 1 address associated with the
|
|
# name, it is a multi-homed host. For each address
|
|
# look up the aliases since the aliases are associated
|
|
# with the address, not the canonical name.
|
|
#
|
|
foreach $canonical (keys %Hosts)
|
|
{
|
|
my @addrs = split(' ', $Hosts{$canonical});
|
|
my $numaddrs = $#addrs + 1;
|
|
foreach my $addr (@addrs)
|
|
{
|
|
|
|
#
|
|
# Print address record for canonical name.
|
|
#
|
|
if ($Cnames{$canonical} != 1)
|
|
{
|
|
printf DOMAIN "%-20s IN A %s\n", $canonical, $addr;
|
|
}
|
|
else
|
|
{
|
|
my $rsp = {};
|
|
$rsp->{data}->[0] =
|
|
"$canonical - cannot create A record because CNAME exists for name.\n";
|
|
xCAT::MsgUtils->message("E", $rsp, $callback, 1);
|
|
}
|
|
|
|
#
|
|
# Print cname or address records for each alias.
|
|
# If this is a multi-homed host, print an address
|
|
# record for each alias. If this is a single address
|
|
# host, print a cname record.
|
|
#
|
|
my $alias;
|
|
if ($doaliases)
|
|
{
|
|
my @aliases = split(' ', $Aliases{$addr});
|
|
foreach $alias (@aliases)
|
|
{
|
|
|
|
#
|
|
# Skip over the alias if the alias and canonical
|
|
# name only differ in that one of them has the
|
|
# domain appended to it.
|
|
#
|
|
next
|
|
if ($dontdodomains && $alias =~ /\./); # skip domain names
|
|
$alias =~ s/$Domainpattern//;
|
|
if ($alias eq $canonical)
|
|
{
|
|
next;
|
|
}
|
|
unless ($alias =~ /^[a-z0-9-]+$/i) {
|
|
xCAT::MsgUtils->message("E", {errorcode=>[1],error=>["$canonical alias $alias contains invalid characters, skipping entry"]}, $callback, 1);
|
|
next;
|
|
}
|
|
|
|
my $aliasforallnames = 0;
|
|
if ($numaddrs > 1)
|
|
{
|
|
|
|
#
|
|
# If alias exists for *all* addresses of this host, we
|
|
# can use a CNAME instead of an address record.
|
|
#
|
|
my $aliasforallnames = 1;
|
|
my $xalias = $alias . " "; # every alias ends with blank
|
|
my @xaddrs = split(' ', $Hosts{$canonical});
|
|
foreach my $xaddr (@xaddrs)
|
|
{
|
|
if (!($Aliases{$xaddr} =~ /\b$xalias/))
|
|
{
|
|
$aliasforallnames = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (($numaddrs > 1) && !$aliasforallnames)
|
|
{
|
|
printf DOMAIN "%-20s IN A %s\n", $alias, $addr;
|
|
}
|
|
else
|
|
{
|
|
|
|
#
|
|
# Flag aliases that have already been used
|
|
# in CNAME records or have A records.
|
|
#
|
|
if (($Cnames{$alias} != 1) && (!$Hosts{$alias}))
|
|
{
|
|
printf DOMAIN "%-20s IN CNAME %s.%s.\n", $alias,
|
|
$canonical, $Domain;
|
|
$Cnames{$alias} = 1;
|
|
}
|
|
else
|
|
{
|
|
my $rsp = {};
|
|
$rsp->{data}->[0] =
|
|
"$alias - CNAME or A exists already. alias ignored.\n";
|
|
xCAT::MsgUtils->message("E", $rsp, $callback, 1);
|
|
}
|
|
}
|
|
|
|
if ($aliasforallnames)
|
|
{
|
|
|
|
#
|
|
# Since a CNAME record was created, remove this
|
|
# name from the alias list so we don't encounter
|
|
# it again for the next address of this host.
|
|
#
|
|
my $xalias = $alias . " "; # every alias ends with blank
|
|
my @xaddrs = split(' ', $Hosts{$canonical});
|
|
my $xaddr;
|
|
foreach $xaddr (@xaddrs)
|
|
{
|
|
$Aliases{$xaddr} =~ s/\b$xalias//;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if ($domx)
|
|
{
|
|
&MX($callback, $canonical, @addrs);
|
|
}
|
|
if ($dotxt)
|
|
{
|
|
&TXT($canonical, @addrs);
|
|
}
|
|
if ($Commentfile ne "")
|
|
{
|
|
&DO_COMMENTS($callback, $canonical, @addrs);
|
|
}
|
|
}
|
|
|
|
# Deal with spcl's
|
|
if (-r "spcl.$Domainfile")
|
|
{
|
|
print DOMAIN "\$INCLUDE spcl.$Domainfile\n";
|
|
}
|
|
my $file;
|
|
my $n;
|
|
foreach $n (@Networks)
|
|
{
|
|
if (-r "spcl.$n")
|
|
{
|
|
$file = "DB.$n";
|
|
print $file "\$INCLUDE spcl.$n\n";
|
|
}
|
|
}
|
|
|
|
# generate boot.* files
|
|
&GEN_BOOT($callback);
|
|
my $rsp = {};
|
|
$rsp->{data}->[0] = "Setup of DNS complete.";
|
|
xCAT::MsgUtils->message("I", $rsp, $callback);
|
|
return 0;
|
|
}
|
|
|
|
#
|
|
# Generate resource record data for
|
|
# strings from the commment field that
|
|
# are found in the comment file (-C).
|
|
#
|
|
sub DO_COMMENTS
|
|
{
|
|
my ($callback, $canonical, @addrs) = @_;
|
|
my (@c, $c, $a, $comments);
|
|
|
|
if (!$Commentfileread)
|
|
{
|
|
unless (open(F, $Commentfile))
|
|
{
|
|
my $rsp = {};
|
|
$rsp->{data}->[0] = "Unable to open file $Commentfile: $!.\n";
|
|
xCAT::MsgUtils->message("E", $rsp, $callback, 1);
|
|
exit 1;
|
|
}
|
|
$Commentfileread++;
|
|
while (<F>)
|
|
{
|
|
chop;
|
|
my ($key, $c) = split(':', $_, 2);
|
|
$CommentRRs{$key} = $c;
|
|
}
|
|
close(F);
|
|
}
|
|
|
|
my $key;
|
|
foreach $a (@addrs)
|
|
{
|
|
$key = "$canonical-$a";
|
|
$comments .= " $Comments{$key}";
|
|
}
|
|
|
|
@c = split(' ', $comments);
|
|
foreach $c (@c)
|
|
{
|
|
if ($CommentRRs{$c})
|
|
{
|
|
printf DOMAIN "%-20s %s\n", $canonical, $CommentRRs{$c};
|
|
}
|
|
}
|
|
}
|
|
|
|
#
|
|
# Generate MX record data
|
|
#
|
|
sub MX
|
|
{
|
|
my ($callback, $canonical, @addrs) = @_;
|
|
my ($first, $a, $key, $comments);
|
|
|
|
if ($Cnames{$canonical})
|
|
{
|
|
my $rsp = {};
|
|
$rsp->{data}->[0] =
|
|
"$canonical - cannot create MX record because CNAME exists for name.\n";
|
|
xCAT::MsgUtils->message("E", $rsp, $callback, 1);
|
|
return;
|
|
}
|
|
$first = 1;
|
|
|
|
foreach $a (@addrs)
|
|
{
|
|
$key = "$canonical-$a";
|
|
$comments .= " $Comments{$key}";
|
|
}
|
|
|
|
if ($comments !~ /\[no smtp\]/)
|
|
{
|
|
|
|
# Add WKS if requested
|
|
if ($dowks)
|
|
{
|
|
foreach $a (@addrs)
|
|
{
|
|
printf DOMAIN "%-20s IN WKS %s TCP SMTP\n", $canonical, $a;
|
|
}
|
|
}
|
|
printf DOMAIN "%-20s IN MX %s %s.%s.\n", $canonical, $DefMxWeight,
|
|
$canonical, $Domain;
|
|
$first = 0;
|
|
}
|
|
if ($#Mx >= 0)
|
|
{
|
|
foreach $a (@Mx)
|
|
{
|
|
if ($first)
|
|
{
|
|
printf DOMAIN "%-20s IN MX %s\n", $canonical, $a;
|
|
$first = 0;
|
|
}
|
|
else
|
|
{
|
|
printf DOMAIN "%-20s IN MX %s\n", "", $a;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
#
|
|
# Generate TXT record data
|
|
#
|
|
sub TXT
|
|
{
|
|
my ($canonical, @addrs) = @_;
|
|
my ($a, $key, $comments);
|
|
|
|
foreach $a (@addrs)
|
|
{
|
|
$key = "$canonical-$a";
|
|
$comments .= " $Comments{$key}";
|
|
}
|
|
$comments =~ s/\[no smtp\]//g;
|
|
$comments =~ s/^\s*//;
|
|
$comments =~ s/\s*$//;
|
|
|
|
if ($comments ne "")
|
|
{
|
|
printf DOMAIN "%s IN TXT \"%s\"\n", $canonical, $comments;
|
|
}
|
|
}
|
|
|
|
#
|
|
# Create the SOA record at the beginning of the file
|
|
#
|
|
sub MAKE_SOA
|
|
{
|
|
my ($callback, $fname, $file) = @_;
|
|
my ($s);
|
|
|
|
if (-s $fname)
|
|
{
|
|
|
|
unless (open($file, "$fname"))
|
|
{
|
|
my $rsp = {};
|
|
$rsp->{data}->[0] = "Unable to open $fname: $!.\n";
|
|
xCAT::MsgUtils->message("E", $rsp, $callback, 1);
|
|
exit 1;
|
|
}
|
|
$_ = <$file>;
|
|
chop;
|
|
if (/\($/)
|
|
{
|
|
my $junk;
|
|
if (!$soa_warned)
|
|
{
|
|
my $rsp = {};
|
|
$rsp->{data}->[0] = "Converting SOA format to new style.\n";
|
|
xCAT::MsgUtils->message("E", $rsp, $callback, 1);
|
|
$soa_warned++;
|
|
}
|
|
if ($ForceSerial > 0)
|
|
{
|
|
$Serial = $ForceSerial;
|
|
}
|
|
else
|
|
{
|
|
($Serial, $junk) = split(' ', <$file>, 2);
|
|
$Serial++;
|
|
if ($UseDateInSerial && ($DateSerial > $Serial))
|
|
{
|
|
$Serial = $DateSerial;
|
|
}
|
|
}
|
|
($Refresh, $junk) = split(' ', <$file>, 2);
|
|
($Retry, $junk) = split(' ', <$file>, 2);
|
|
($Expire, $junk) = split(' ', <$file>, 2);
|
|
($Ttl, $junk) = split(' ', <$file>, 2);
|
|
}
|
|
else
|
|
{
|
|
if (/TTL/)
|
|
{
|
|
$_ = <$file>;
|
|
}
|
|
split(' ');
|
|
if ($#_ == 11)
|
|
{
|
|
if ($ForceSerial > 0)
|
|
{
|
|
$Serial = $ForceSerial;
|
|
}
|
|
else
|
|
{
|
|
$Serial = ++$_[6];
|
|
if ($UseDateInSerial && ($DateSerial > $Serial))
|
|
{
|
|
$Serial = $DateSerial;
|
|
}
|
|
}
|
|
$Refresh = $_[7];
|
|
$Retry = $_[8];
|
|
$Expire = $_[9];
|
|
$Ttl = $_[10];
|
|
}
|
|
else
|
|
{
|
|
my $rsp = {};
|
|
$rsp->{data}->[0] = "Improper format SOA in $fname.\n";
|
|
xCAT::MsgUtils->message("E", $rsp, $callback, 1);
|
|
exit(1);
|
|
}
|
|
}
|
|
if ($UseDefSOAValues)
|
|
{
|
|
$Refresh = $DefRefresh;
|
|
$Retry = $DefRetry;
|
|
$Expire = $DefExpire;
|
|
$Ttl = $DefTtl;
|
|
}
|
|
close($file);
|
|
}
|
|
else
|
|
{
|
|
if ($ForceSerial > 0)
|
|
{
|
|
$Serial = $ForceSerial;
|
|
}
|
|
else
|
|
{
|
|
$Serial = $DefSerial;
|
|
if ($UseDateInSerial && ($DateSerial > $Serial))
|
|
{
|
|
$Serial = $DateSerial;
|
|
}
|
|
}
|
|
$Refresh = $DefRefresh;
|
|
$Retry = $DefRetry;
|
|
$Expire = $DefExpire;
|
|
$Ttl = $DefTtl;
|
|
close($file);
|
|
}
|
|
|
|
unless (open($file, "> $fname"))
|
|
{
|
|
my $rsp = {};
|
|
$rsp->{data}->[0] = "Unable to open $fname: $!.\n";
|
|
xCAT::MsgUtils->message("E", $rsp, $callback, 1);
|
|
exit 1;
|
|
}
|
|
print $file '$TTL 86400' . "\n";
|
|
print $file "\@ IN SOA $RespHost $RespUser ";
|
|
print $file "( $Serial $Refresh $Retry $Expire $Ttl )\n";
|
|
foreach $s (@Servers)
|
|
{
|
|
print $file " IN NS $s\n";
|
|
}
|
|
print $file "\n";
|
|
}
|
|
|
|
#
|
|
# Reverse the octets of an IP address and append
|
|
# in-addr.arpa.
|
|
#
|
|
sub REVERSE
|
|
{
|
|
join('.', reverse(split('\.', $_[0]))) . '.IN-ADDR.ARPA.';
|
|
}
|
|
|
|
#
|
|
# Establish what we will be using for SOA records
|
|
#
|
|
sub FIXUP
|
|
{
|
|
my $callback = shift;
|
|
my ($s);
|
|
|
|
if ($Host =~ /\./)
|
|
{
|
|
$RespHost = "$Host.";
|
|
}
|
|
else
|
|
{
|
|
$RespHost = "$Host.$Domain.";
|
|
}
|
|
$RespHost =~ s/\.\././g;
|
|
|
|
if ($User =~ /@/)
|
|
{ # -u user@...
|
|
if ($User =~ /\./)
|
|
{
|
|
$RespUser = "$User."; # -u user@terminator.movie.edu
|
|
}
|
|
else
|
|
{
|
|
$RespUser = "$User.$Domain."; # -u user@terminator
|
|
}
|
|
$RespUser =~ s/@/./;
|
|
}
|
|
elsif ($User =~ /\./)
|
|
{
|
|
$RespUser = "$User."; # -u user.terminator.movie.edu
|
|
}
|
|
else
|
|
{
|
|
$RespUser = "$User.$RespHost"; # -u user
|
|
}
|
|
$RespUser =~ s/\.\././g; # Strip any ".."'s to "."
|
|
|
|
# Clean up nameservers
|
|
if (!@Servers)
|
|
{
|
|
my $rsp = {};
|
|
$rsp->{data}->[0] =
|
|
"No -s option specified. Assuming \"-s $Host.$Domain\".\n";
|
|
xCAT::MsgUtils->message("E", $rsp, $callback, 1);
|
|
push(@Servers, "$Host.$Domain.");
|
|
}
|
|
else
|
|
{
|
|
foreach $s (@Servers)
|
|
{
|
|
if ($s !~ /\./)
|
|
{
|
|
$s .= ".$Domain";
|
|
}
|
|
if ($s !~ /\.$/)
|
|
{
|
|
$s .= ".";
|
|
}
|
|
}
|
|
}
|
|
|
|
# Clean up MX hosts
|
|
foreach $s (@Mx)
|
|
{
|
|
$s =~ s/:/ /;
|
|
if ($s !~ /\./)
|
|
{
|
|
$s .= ".$Domain";
|
|
}
|
|
if ($s !~ /\.$/)
|
|
{
|
|
$s .= ".";
|
|
}
|
|
}
|
|
|
|
# Now open boot file (named.conf) and print saved data
|
|
unless (open(BOOT, "> $Bootfile"))
|
|
{
|
|
my $rsp = {};
|
|
$rsp->{data}->[0] = "Unable to open $Bootfile.\n";
|
|
xCAT::MsgUtils->message("E", $rsp, $callback, 1);
|
|
exit 1;
|
|
}
|
|
|
|
#
|
|
# Write either the version 4 boot file directives or the
|
|
# version 8 boot file directives.
|
|
#
|
|
|
|
if ($Version == 4)
|
|
{
|
|
print BOOT "\ndirectory $DBDir\n";
|
|
foreach my $line (@bootmsgs_v4)
|
|
{
|
|
print BOOT $line;
|
|
}
|
|
print BOOT "cache\t. db.cache\n";
|
|
if (-r "spcl.boot")
|
|
{
|
|
print BOOT "include\tspcl.boot\n";
|
|
}
|
|
}
|
|
else
|
|
{
|
|
print BOOT qq|\noptions {\n\tdirectory "$DBDir";\n|;
|
|
if (@forwarders)
|
|
{
|
|
print BOOT qq|\tforwarders {\n|;
|
|
foreach (@forwarders)
|
|
{
|
|
print BOOT qq|\t\t$_;\n|;
|
|
}
|
|
print BOOT qq|\t};\n|;
|
|
}
|
|
if (-r "spcl.options")
|
|
{
|
|
print BOOT "\t# These options came from the file spcl.options\n";
|
|
|
|
#
|
|
# Copy the options in since "include" cannot be used
|
|
# within a statement.
|
|
#
|
|
unless (open(OPTIONS, "<spcl.options"))
|
|
{
|
|
my $rsp = {};
|
|
$rsp->{data}->[0] = "Unable to open spcl.options.\n";
|
|
xCAT::MsgUtils->message("E", $rsp, $callback, 1);
|
|
exit 1;
|
|
}
|
|
while (<OPTIONS>)
|
|
{
|
|
print BOOT;
|
|
}
|
|
close(OPTIONS);
|
|
}
|
|
print BOOT qq|};\n\n|;
|
|
foreach my $line (@bootmsgs_v8)
|
|
{
|
|
print BOOT $line;
|
|
}
|
|
|
|
# hint zone is also needed for DNS forwarders on AIX
|
|
if (xCAT::Utils->isAIX())
|
|
{
|
|
print BOOT
|
|
qq|zone "." in {\n\ttype hint;\n\tfile "db.cache";\n};\n\n|;
|
|
}
|
|
else
|
|
{
|
|
unless (@forwarders)
|
|
{
|
|
print BOOT
|
|
qq|zone "." in {\n\ttype hint;\n\tfile "db.cache";\n};\n\n|;
|
|
}
|
|
}
|
|
|
|
if (-r "spcl.boot")
|
|
{
|
|
print BOOT qq|include "spcl.boot";\n\n|;
|
|
}
|
|
}
|
|
|
|
close(BOOT);
|
|
|
|
# Go ahead and start creating files and making SOA's
|
|
my $x1;
|
|
my $x2;
|
|
foreach my $i (@makesoa)
|
|
{
|
|
($x1, $x2) = split(' ', $i);
|
|
&MAKE_SOA($callback, $x1, $x2);
|
|
}
|
|
printf DOMAIN "%-20s IN A 127.0.0.1\n", "localhost";
|
|
|
|
my $file = "DB.127.0.0.1";
|
|
&MAKE_SOA($callback, $DBDir . "db.127.0.0", $file);
|
|
if (xCAT::Utils->isAIX())
|
|
{
|
|
# if forwarders is set, we need to create the hint file for root name servers.
|
|
if (@forwarders)
|
|
{
|
|
my $tmpfile = $DBDir . "db.cache";
|
|
my $cmd = qq~dig @"$forwarders[0]" . ns >> $tmpfile~;
|
|
my $outref = xCAT::Utils->runcmd("$cmd", 0);
|
|
if ($::RUNCMD_RC != 0)
|
|
{
|
|
my $rsp = {};
|
|
$rsp->{data}->[0] = "Could not run command: $cmd.\n";
|
|
xCAT::MsgUtils->message("E", $rsp, $callback, 1);
|
|
exit 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
my $nothing;
|
|
open($nothing, ">>", $DBDir . "db.cache");
|
|
close($nothing);
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
my $nothing;
|
|
open($nothing, ">>", $DBDir . "db.cache");
|
|
close($nothing);
|
|
|
|
}
|
|
printf $file "%-30s\tIN PTR localhost.\n", &REVERSE("127.0.0.1");
|
|
close($file);
|
|
}
|
|
|
|
sub PARSEARGS
|
|
{
|
|
my ($callback, @args) = @_;
|
|
my ($i, $net, $subnetmask, $option, $tmp1);
|
|
my ($file, @newargs, @targs);
|
|
my ($sec, $min, $hour, $mday, $mon, $year, $rest);
|
|
($sec, $min, $hour, $mday, $mon, $year, $rest) = localtime(time);
|
|
$DateSerial =
|
|
($mday * 100) + (($mon + 1) * 10000) + (($year + 1900) * 1000000);
|
|
|
|
$i = 0;
|
|
while ($i <= $#args)
|
|
{
|
|
$option = $args[$i];
|
|
if ($option eq "-d")
|
|
{
|
|
if ($Domain ne "")
|
|
{
|
|
my $rsp = {};
|
|
$rsp->{data}->[0] = "Only one -d option allowed.\n";
|
|
xCAT::MsgUtils->message("E", $rsp, $callback, 1);
|
|
exit(1);
|
|
}
|
|
$Domain = $args[++$i];
|
|
$Domainpattern = "." . $Domain;
|
|
$Domainpattern =~ s/\./\\./g; # for stripping off domain
|
|
|
|
# Add entry to the boot file.
|
|
$Domainfile = $Domain;
|
|
$Domainfile =~ s/\..*//;
|
|
push(@makesoa, $DBDir . "db.$Domainfile DOMAIN");
|
|
push(@bootmsgs_v4, "primary\t$Domain db.$Domainfile\n");
|
|
push(@bootmsgs_v8,
|
|
qq|zone "$Domain" in {\n\ttype master;\n\tfile "db.$Domainfile";\n};\n\n|
|
|
);
|
|
|
|
}
|
|
elsif ($option eq "-f")
|
|
{
|
|
$file = $args[++$i];
|
|
unless (open(F, $file))
|
|
{
|
|
my $rsp = {};
|
|
$rsp->{data}->[0] = "Unable to open args file $file: $!.\n";
|
|
xCAT::MsgUtils->message("E", $rsp, $callback, 1);
|
|
exit 1;
|
|
}
|
|
while (<F>)
|
|
{
|
|
next if (/^#/);
|
|
next if (/^$/);
|
|
chop;
|
|
@targs = split(' ');
|
|
push(@newargs, @targs);
|
|
}
|
|
close(F);
|
|
&PARSEARGS($callback, @newargs);
|
|
|
|
}
|
|
elsif ($option eq "-z")
|
|
{
|
|
$Bootsecsaveaddr = $args[++$i];
|
|
if (!defined($Bootsecaddr))
|
|
{
|
|
$Bootsecaddr = $Bootsecsaveaddr;
|
|
}
|
|
|
|
}
|
|
elsif ($option eq "-Z")
|
|
{
|
|
$Bootsecaddr = $args[++$i];
|
|
if (!defined($Bootsecsaveaddr))
|
|
{
|
|
$Bootsecsaveaddr = $Bootsecaddr;
|
|
}
|
|
|
|
}
|
|
elsif ($option eq "-b")
|
|
{
|
|
$Bootfile = $args[++$i];
|
|
|
|
}
|
|
elsif ($option eq "-A")
|
|
{
|
|
$doaliases = 0;
|
|
|
|
}
|
|
elsif ($option eq "-M")
|
|
{
|
|
$domx = 0;
|
|
|
|
}
|
|
elsif ($option eq "-w")
|
|
{
|
|
$dowks = 1;
|
|
|
|
}
|
|
elsif ($option eq "-D")
|
|
{
|
|
$dontdodomains = 1;
|
|
|
|
}
|
|
elsif ($option eq "-t")
|
|
{
|
|
$dotxt = 1;
|
|
|
|
}
|
|
elsif ($option eq "-u")
|
|
{
|
|
$User = $args[++$i];
|
|
|
|
}
|
|
elsif ($option eq "-s")
|
|
{
|
|
while ($args[++$i] !~ /^-/ && $i <= $#args)
|
|
{
|
|
push(@Servers, $args[$i]);
|
|
}
|
|
$i--;
|
|
|
|
}
|
|
elsif ($option eq "-m")
|
|
{
|
|
if ($args[++$i] !~ /:/)
|
|
{
|
|
my $rsp = {};
|
|
$rsp->{data}->[0] =
|
|
"Improper format for -m option ignored ($args[$i]).\n";
|
|
xCAT::MsgUtils->message("E", $rsp, $callback, 1);
|
|
}
|
|
push(@Mx, $args[$i]);
|
|
|
|
}
|
|
elsif ($option eq "-c")
|
|
{
|
|
my $tmp1 = $args[++$i];
|
|
if ($tmp1 !~ /\./)
|
|
{
|
|
$tmp1 .= ".$Domain";
|
|
}
|
|
if ($Domain eq $tmp1)
|
|
{
|
|
my $rsp = {};
|
|
$rsp->{data}->[0] =
|
|
"Domain for -c option must not match domain for -d option.\n";
|
|
xCAT::MsgUtils->message("E", $rsp, $callback, 1);
|
|
exit(1);
|
|
}
|
|
my $tmp2 = $tmp1;
|
|
$tmp2 =~ s/\./\\./g;
|
|
$cpatrel{$tmp2} = $tmp1;
|
|
push(@cpats, $tmp2);
|
|
|
|
}
|
|
elsif ($option eq "-e")
|
|
{
|
|
$tmp1 = $args[++$i];
|
|
if ($tmp1 !~ /\./)
|
|
{
|
|
$tmp1 .= ".$Domain";
|
|
}
|
|
$tmp1 =~ s/\./\\./g;
|
|
push(@elimpats, $tmp1);
|
|
|
|
}
|
|
elsif ($option eq "-h")
|
|
{
|
|
$Host = $args[++$i];
|
|
|
|
}
|
|
elsif ($option eq "-o")
|
|
{
|
|
if ($args[++$i] !~ /^[:\d]*$/
|
|
|| split(':', $args[$i]) != 4)
|
|
{
|
|
my $rsp = {};
|
|
$rsp->{data}->[0] = "Improper format for -o ($args[$i]).\n";
|
|
xCAT::MsgUtils->message("E", $rsp, $callback, 1);
|
|
exit(1);
|
|
}
|
|
($DefRefresh, $DefRetry, $DefExpire, $DefTtl) =
|
|
split(':', $args[$i]);
|
|
$UseDefSOAValues = 1;
|
|
|
|
}
|
|
elsif ($option eq "-i")
|
|
{
|
|
$ForceSerial = $args[++$i];
|
|
|
|
}
|
|
elsif ($option eq "-H")
|
|
{
|
|
$Hostfile = $args[++$i];
|
|
if (!-r $Hostfile || -z $Hostfile)
|
|
{
|
|
my $rsp = {};
|
|
$rsp->{data}->[0] =
|
|
"Invalid file specified for -H ($Hostfile).\n";
|
|
xCAT::MsgUtils->message("E", $rsp, $callback, 1);
|
|
exit(1);
|
|
}
|
|
|
|
}
|
|
elsif ($option eq "-C")
|
|
{
|
|
$Commentfile = $args[++$i];
|
|
if (!-r $Commentfile || -z $Commentfile)
|
|
{
|
|
my $rsp = {};
|
|
$rsp->{data}->[0] =
|
|
"Invalid file specified for -C ($Commentfile).\n";
|
|
xCAT::MsgUtils->message("E", $rsp, $callback, 1);
|
|
exit(1);
|
|
}
|
|
|
|
}
|
|
elsif ($option eq "-N")
|
|
{
|
|
$Defsubnetmask = $args[++$i];
|
|
if ($Defsubnetmask !~ /^[.\d]*$/
|
|
|| split('\.', $Defsubnetmask) != 4)
|
|
{
|
|
my $rsp = {};
|
|
$rsp->{data}->[0] = "Improper subnet mask ($Defsubnetmask).\n";
|
|
xCAT::MsgUtils->message("E", $rsp, $callback, 1);
|
|
exit(1);
|
|
}
|
|
if ($#Networks >= 0)
|
|
{
|
|
my $rsp = {};
|
|
$rsp->{data}->[0] =
|
|
"-N option should be specified before any -n options.\n";
|
|
xCAT::MsgUtils->message("E", $rsp, $callback, 1);
|
|
}
|
|
|
|
}
|
|
elsif ($option eq "-n")
|
|
{
|
|
(my $tnet, $subnetmask) = split(':', $args[++$i]);
|
|
$net = "";
|
|
my @netm = split(/\./, $subnetmask);
|
|
my @tnets = split(/\./, $tnet);
|
|
foreach (0 .. 3)
|
|
{
|
|
my $res = ($tnets[$_] + 0) & ($netm[$_] + 0);
|
|
if ($netm[$_])
|
|
{
|
|
$net .= $res . '.';
|
|
}
|
|
}
|
|
$net =~ s/\.$//;
|
|
|
|
if (not $net)
|
|
{
|
|
my $rsp = {};
|
|
$rsp->{data}->[0] =
|
|
"Empty network found in networks table (i.e. ,,),This is almost certainly going to cause a problem....\n";
|
|
xCAT::MsgUtils->message("E", $rsp, $callback, 1);
|
|
}
|
|
if ($subnetmask eq "")
|
|
{
|
|
my $rsp = {};
|
|
$rsp->{data}->[0] =
|
|
"$net has no defined netmask in the networks table, the result will probably be wrong.\n";
|
|
xCAT::MsgUtils->message("E", $rsp, $callback, 1);
|
|
foreach $tmp1 (&SUBNETS($net, $Defsubnetmask))
|
|
{
|
|
&BUILDNET($tmp1);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ($subnetmask !~ /^[.\d]*$/
|
|
|| split('\.', $subnetmask) != 4)
|
|
{
|
|
my $rsp = {};
|
|
$rsp->{data}->[0] = "Improper subnet mask ($subnetmask).\n";
|
|
xCAT::MsgUtils->message("E", $rsp, $callback, 1);
|
|
exit(1);
|
|
}
|
|
foreach $tmp1 (&SUBNETS($net, $subnetmask))
|
|
{
|
|
&BUILDNET($tmp1);
|
|
}
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
if ($option =~ /^-.*/)
|
|
{
|
|
my $rsp = {};
|
|
$rsp->{data}->[0] = "Unknown option: $option ... ignored.\n";
|
|
xCAT::MsgUtils->message("E", $rsp, $callback, 1);
|
|
}
|
|
}
|
|
$i++;
|
|
}
|
|
|
|
if (!@Networks || $Domain eq "")
|
|
{
|
|
my $rsp = {};
|
|
$rsp->{data}->[0] = "Must specify one -d and at least one -n.\n";
|
|
xCAT::MsgUtils->message("E", $rsp, $callback, 1);
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
sub BUILDNET
|
|
{
|
|
my ($net) = @_;
|
|
|
|
push(@Networks, $net);
|
|
|
|
#
|
|
# Create pattern to match against.
|
|
# The dots must be changed to \. so they
|
|
# aren't used as wildcards.
|
|
#
|
|
my $netpat = $net;
|
|
$netpat =~ s/\./\\./g;
|
|
push(@Netpatterns, $netpat);
|
|
|
|
#
|
|
# Create db files for PTR records.
|
|
# Save the file names in an array for future use.
|
|
#
|
|
my $netfile = "DB.$net";
|
|
$Netfiles{$netpat} = $netfile;
|
|
push(@makesoa, $DBDir . "db.$net $netfile");
|
|
|
|
# Add entry to the boot file.
|
|
my $revaddr = &REVERSE($net);
|
|
chop($revaddr); # remove trailing dot
|
|
push(@bootmsgs_v4, "primary $revaddr db.$net\n");
|
|
push(@bootmsgs_v8,
|
|
qq|zone "$revaddr" in {\n\ttype master;\n\tfile "db.$net";\n};\n\n|);
|
|
}
|
|
|
|
#
|
|
# Calculate all the subnets from a network number and mask.
|
|
# This was originally written for awk, not perl.
|
|
#
|
|
sub SUBNETS
|
|
{
|
|
my ($network, $mask) = @_;
|
|
my (@ans, @net, @mask, $buf, $number, $i, $j, $howmany);
|
|
|
|
@net = split(/\./, $network);
|
|
@mask = split(/\./, $mask);
|
|
$number = '';
|
|
|
|
#
|
|
# Only expand bytes 1, 2, or 3
|
|
# for DNS purposes
|
|
#
|
|
for ($i = 0 ; $i < 4 ; $i++)
|
|
{
|
|
if ($mask[$i] == 255)
|
|
{
|
|
$number = $number . $net[$i] . '.';
|
|
}
|
|
elsif (($mask[$i] == 0) || $mask[$i] eq '')
|
|
{
|
|
push(@ans, $network);
|
|
last;
|
|
}
|
|
else
|
|
{
|
|
|
|
#
|
|
# This should be done as a bit-wise or
|
|
# but awk does not have an or symbol
|
|
#
|
|
$howmany = 255 - $mask[$i];
|
|
for ($j = 0 ; $j <= $howmany ; $j++)
|
|
{
|
|
if ($net[$i] + $j <= 255)
|
|
{
|
|
$buf = sprintf("%s%d", $number, $net[$i] + $j);
|
|
push(@ans, $buf);
|
|
}
|
|
}
|
|
last;
|
|
}
|
|
}
|
|
|
|
if ($#ans == -1)
|
|
{
|
|
push(@ans, $network);
|
|
}
|
|
|
|
@ans;
|
|
}
|
|
|
|
sub GEN_BOOT
|
|
{
|
|
$callback = shift;
|
|
my ($revaddr, $n);
|
|
|
|
if (0)
|
|
{ #! -e "boot.cacheonly") { DISABLE THIS PART
|
|
#
|
|
# Create a boot file for a cache-only server
|
|
#
|
|
unless (open(F, ">boot.cacheonly"))
|
|
{
|
|
my $rsp = {};
|
|
$rsp->{data}->[0] = "Unable to open boot.cacheonly: $!.\n";
|
|
xCAT::MsgUtils->message("E", $rsp, $callback, 1);
|
|
exit 1;
|
|
}
|
|
if ($Version == 4)
|
|
{
|
|
print F "directory\t$DBDir\n";
|
|
print F "primary\t\t0.0.127.IN-ADDR.ARPA db.127.0.0\n";
|
|
print F "cache\t\t. db.cache\n";
|
|
if (-r "spcl.cacheonly")
|
|
{
|
|
printf F "include\t\tspcl.cacheonly\n";
|
|
}
|
|
close(F);
|
|
}
|
|
else
|
|
{
|
|
print F qq|\noptions {\n\tdirectory "$DBDir";\n|;
|
|
if (@forwarders)
|
|
{
|
|
print F qq|\tforwarders {\n|;
|
|
foreach (@forwarders)
|
|
{
|
|
print F qq|\t\t$_;\n|;
|
|
}
|
|
print F qq|\t};\n|;
|
|
}
|
|
if (-r "spcl.options")
|
|
{
|
|
print F "\t# These options came from the file spcl.options\n";
|
|
|
|
#
|
|
# Copy the options in since "include" cannot be used
|
|
# within a statement.
|
|
#
|
|
|
|
unless (open(OPTIONS, "<spcl.options"))
|
|
{
|
|
my $rsp = {};
|
|
$rsp->{data}->[0] = "Unable to open boot.cacheonly: $!.\n";
|
|
xCAT::MsgUtils->message("E", $rsp, $callback, 1);
|
|
exit 1;
|
|
}
|
|
|
|
while (<OPTIONS>)
|
|
{
|
|
print F;
|
|
}
|
|
close(OPTIONS);
|
|
}
|
|
print F qq|};\n\n|;
|
|
print F qq|zone "0.0.127.IN-ADDR.ARPA" in {\n\ttype master;|;
|
|
print F qq|\n\tfile "db.127.0.0";|;
|
|
print F qq|\n\tnotify no;\n};\n\n|;
|
|
|
|
#print F qq|zone "." in {\n\ttype hint;\n\tfile "db.cache";\n};\n\n|;
|
|
if (-r "spcl.cacheonly")
|
|
{
|
|
print F qq|include "spcl.cacheonly";\n\n|;
|
|
}
|
|
}
|
|
}
|
|
|
|
#
|
|
# Create a 2 boot files for a secondary (slave) servers.
|
|
# One boot file doesn't save the zone data in a file. The
|
|
# other boot file does save the zone data in a file.
|
|
#
|
|
if (defined($Bootsecaddr))
|
|
{
|
|
unless (open(F, ">boot.sec"))
|
|
{
|
|
my $rsp = {};
|
|
$rsp->{data}->[0] = "Unable to open boot.sec: $!.\n";
|
|
xCAT::MsgUtils->message("E", $rsp, $callback, 1);
|
|
exit 1;
|
|
}
|
|
|
|
if ($Version == 4)
|
|
{
|
|
print F "directory\t$DBDir\n";
|
|
print F "primary\t\t0.0.127.IN-ADDR.ARPA db.127.0.0\n";
|
|
printf F "secondary\t%-23s $Bootsecaddr\n", $Domain;
|
|
foreach $n (@Networks)
|
|
{
|
|
$revaddr = &REVERSE($n);
|
|
chop($revaddr);
|
|
printf F "secondary\t%-23s $Bootsecaddr\n", $revaddr;
|
|
}
|
|
print F "cache\t\t. db.cache\n";
|
|
if (-r "spcl.boot")
|
|
{
|
|
printf F "include\t\tspcl.boot\n";
|
|
}
|
|
}
|
|
else
|
|
{
|
|
print F qq|\noptions {\n\tdirectory "$DBDir";\n|;
|
|
if (-r "spcl.options")
|
|
{
|
|
print F "\t# These options came from the file spcl.options\n";
|
|
|
|
#
|
|
# Copy the options in since "include" cannot be used
|
|
# within a statement.
|
|
#
|
|
unless (open(OPTIONS, "<spcl.options"))
|
|
{
|
|
my $rsp = {};
|
|
$rsp->{data}->[0] = "Unable to open spcl.options.\n";
|
|
xCAT::MsgUtils->message("E", $rsp, $callback, 1);
|
|
exit 1;
|
|
}
|
|
|
|
while (<OPTIONS>)
|
|
{
|
|
print F;
|
|
}
|
|
close(OPTIONS);
|
|
}
|
|
print F qq|};\n\n|;
|
|
print F qq|zone "0.0.127.IN-ADDR.ARPA" in {\n\ttype master;|;
|
|
print F qq|\n\tfile "db.127.0.0";|;
|
|
print F qq|\n\tnotify no;\n};\n\n|;
|
|
print F qq|zone "$Domain" in {\n\ttype slave;\n\tmasters {|;
|
|
print F qq| $Bootsecaddr; };\n};\n\n|;
|
|
|
|
foreach $n (@Networks)
|
|
{
|
|
$revaddr = &REVERSE($n);
|
|
chop($revaddr);
|
|
print F qq|zone "$revaddr" in {\n\ttype slave;\n\tmasters {|;
|
|
print F qq| $Bootsecaddr; };\n};\n\n|;
|
|
}
|
|
|
|
#print F qq|zone "." in {\n\ttype hint;\n\tfile "db.cache";\n};\n\n|;
|
|
if (-r "spcl.boot")
|
|
{
|
|
print F qq|include "spcl.boot";\n\n|;
|
|
}
|
|
}
|
|
close(F);
|
|
|
|
unless (open(F, ">boot.sec.save"))
|
|
{
|
|
my $rsp = {};
|
|
$rsp->{data}->[0] = "Unable to open boot.sec.save: $!.\n";
|
|
xCAT::MsgUtils->message("E", $rsp, $callback, 1);
|
|
exit 1;
|
|
}
|
|
|
|
if ($Version == 4)
|
|
{
|
|
print F "directory\t$DBDir\n";
|
|
print F "primary\t\t0.0.127.IN-ADDR.ARPA db.127.0.0\n";
|
|
printf F "secondary\t%-23s $Bootsecsaveaddr db.%s\n", $Domain,
|
|
$Domainfile;
|
|
foreach $n (@Networks)
|
|
{
|
|
$revaddr = &REVERSE($n);
|
|
chop($revaddr);
|
|
printf F "secondary\t%-23s $Bootsecsaveaddr db.%s\n", $revaddr,
|
|
$n;
|
|
}
|
|
print F "cache\t\t. db.cache\n";
|
|
if (-r "spcl.boot")
|
|
{
|
|
printf F "include\t\tspcl.boot\n";
|
|
}
|
|
}
|
|
else
|
|
{
|
|
print F qq|\noptions {\n\tdirectory "$DBDir";\n|;
|
|
if (-r "spcl.options")
|
|
{
|
|
print F "\t# These options came from the file spcl.options\n";
|
|
|
|
#
|
|
# Copy the options in since "include" cannot be used
|
|
# within a statement.
|
|
#
|
|
unless (open(OPTIONS, "<spcl.options"))
|
|
{
|
|
my $rsp = {};
|
|
$rsp->{data}->[0] = "Can't open spcl.options.\n";
|
|
xCAT::MsgUtils->message("E", $rsp, $callback, 1);
|
|
exit 1;
|
|
}
|
|
while (<OPTIONS>)
|
|
{
|
|
print F;
|
|
}
|
|
close(OPTIONS);
|
|
}
|
|
print F qq|};\n\n|;
|
|
print F qq|zone "0.0.127.IN-ADDR.ARPA" in {\n\ttype master;|;
|
|
print F qq|\n\tfile "db.127.0.0";|;
|
|
print F qq|\n\tnotify no;\n};\n\n|;
|
|
|
|
print F
|
|
qq|zone "$Domain" in {\n\ttype slave;\n\tfile "db.$Domainfile";|;
|
|
print F qq|\n\tmasters { $Bootsecsaveaddr; };\n};\n\n|;
|
|
|
|
foreach $n (@Networks)
|
|
{
|
|
$revaddr = &REVERSE($n);
|
|
chop($revaddr);
|
|
print F
|
|
qq|zone "$revaddr" in {\n\ttype slave;\n\tfile "db.$n";\n\tmasters {|;
|
|
print F qq| $Bootsecsaveaddr; };\n};\n\n|;
|
|
}
|
|
|
|
#print F qq|zone "." in {\n\ttype hint;\n\tfile "db.cache";\n};\n\n|;
|
|
if (-r "spcl.boot")
|
|
{
|
|
print F qq|include "spcl.boot";\n\n|;
|
|
}
|
|
}
|
|
close(F);
|
|
}
|
|
}
|
|
|
|
# subroutine to display the usage
|
|
sub checkusageandversion
|
|
{
|
|
my $callback = shift;
|
|
|
|
# parse the options
|
|
if (
|
|
GetOptions('h|help' => \$::HELP,
|
|
'v|version' => \$::VERSION)
|
|
)
|
|
{
|
|
if ($::HELP)
|
|
{
|
|
my $rsp = {};
|
|
$rsp->{data}->[0] = "Usage:";
|
|
$rsp->{data}->[1] = " makedns <options>";
|
|
$rsp->{data}->[2] = " makedns [-h|--help|-v|--version]";
|
|
$rsp->{data}->[3] = " <options> See man makedns";
|
|
xCAT::MsgUtils->message("I", $rsp, $callback);
|
|
exit 0;
|
|
}
|
|
if ($::VERSION)
|
|
{
|
|
my $version = xCAT::Utils->Version();
|
|
my $rsp = {};
|
|
$rsp->{data}->[0] = "$version";
|
|
xCAT::MsgUtils->message("I", $rsp, $callback);
|
|
exit 0;
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
1;
|