2007-10-26 22:44:33 +00:00
#!/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 ;
2008-07-18 22:21:52 +00:00
use strict ;
2008-10-10 14:03:34 +00:00
no strict "refs" ; #This code is as yet still very broken...
2008-07-18 22:21:52 +00:00
#use warnings;
2007-10-26 22:44:33 +00:00
use Sys::Hostname ;
use Cwd ;
2008-10-09 18:15:08 +00:00
use Getopt::Long ;
2007-10-26 22:44:33 +00:00
use xCAT::Table ;
2008-10-09 18:15:08 +00:00
use xCAT::MsgUtils ;
2007-10-26 22:44:33 +00:00
use Data::Dumper ;
2008-10-10 14:03:34 +00:00
sub handled_commands
{
2007-10-26 22:44:33 +00:00
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 ;
2008-10-10 14:03:34 +00:00
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 = "" ;
2007-10-26 22:44:33 +00:00
my $ Commentfileread = 0 ;
2008-10-10 14:03:34 +00:00
my $ User = "root" ;
my $ RespHost = "" ;
my $ RespUser = "" ;
my $ DefSerial = 1 ;
my $ DefRefresh = 10800 ;
my $ DefRetry = 3600 ;
my $ DefExpire = 604800 ;
my $ DefTtl = 86400 ;
2007-10-26 22:44:33 +00:00
my $ UseDefSOAValues = 0 ;
2008-10-10 14:03:34 +00:00
my $ DefMxWeight = 10 ;
my $ Defsubnetmask = "" ;
my $ ForceSerial = - 1 ;
2007-10-26 22:44:33 +00:00
my $ UseDateInSerial = 1 ;
2008-10-10 14:03:34 +00:00
my $ DateSerial = 0 ;
my $ Version = 8 ;
2007-10-26 22:44:33 +00:00
my $ request ;
my $ callback ;
my @ forwarders ;
2008-07-18 22:21:52 +00:00
#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 ;
2008-10-10 14:03:34 +00:00
sub process_request
{
$ request = shift ;
$ callback = shift ;
% Netfiles = ( ) ;
% Aliases = ( ) ;
$ soa_warned = 0 ;
2008-07-18 22:21:52 +00:00
my $ canonical ;
my $ aliases ;
2008-10-10 14:03:34 +00:00
% Comments = ( ) ;
% CommentRRs = ( ) ;
% Cnames = ( ) ;
% Hosts = ( ) ;
@ Netpatterns = ( ) ;
$ DBDir = "/var/named/" ;
unless ( - d $ DBDir )
{
2008-07-03 13:55:09 +00:00
$ DBDir = "/var/lib/named/" ;
2008-07-02 15:35:12 +00:00
}
2008-10-10 14:03:34 +00:00
2008-10-09 18:15:08 +00:00
# if both do not exist, make /var/named
2008-10-10 14:03:34 +00:00
unless ( - d $ DBDir )
{
2008-10-09 18:15:08 +00:00
$ DBDir = "/var/named/" ;
my $ cmd = "/bin/mkdir $DBDir" ;
my $ outref = xCAT::Utils - > runcmd ( "$cmd" , 0 ) ;
if ( $ ::RUNCMD_RC != 0 )
{
2008-10-10 14:03:34 +00:00
my $ rsp = { } ;
$ rsp - > { data } - > [ 0 ] = "Could not create $DBDir.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback , 1 ) ;
exit 1 ;
2008-10-09 18:15:08 +00:00
}
}
2007-10-26 22:44:33 +00:00
$ Host = hostname ;
2008-07-01 16:22:09 +00:00
$ Host =~ s/\..*// ;
2007-10-26 22:44:33 +00:00
my $ sitetab = xCAT::Table - > new ( 'site' ) ;
2008-10-10 14:03:34 +00:00
unless ( $ sitetab )
{
my $ rsp = { } ;
$ rsp - > { data } - > [ 0 ] = "No site table found.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback , 1 ) ;
2007-10-26 22:44:33 +00:00
return ;
}
2008-10-10 14:03:34 +00:00
my @ args = ( ) ;
if ( $ request - > { arg } )
{
2008-08-14 12:47:48 +00:00
@ args = @ { $ request - > { arg } } ;
2008-10-09 18:15:08 +00:00
@ ARGV = @ { $ request - > { arg } } ;
2008-08-14 12:47:48 +00:00
}
2008-10-09 18:15:08 +00:00
& checkusageandversion ( $ callback ) ;
2008-10-10 14:03:34 +00:00
( my $ fent ) = $ sitetab - > getAttribs ( { key = > 'forwarders' } , 'value' ) ;
if ( $ fent and defined $ fent - > { value } )
{
@ forwarders = split /[,:;]/ , $ fent - > { value } ;
2007-10-26 22:44:33 +00:00
}
2008-10-10 14:03:34 +00:00
unless ( grep /^-d$/ , @ args )
{
( my $ dent ) = $ sitetab - > getAttribs ( { key = > 'domain' } , 'value' ) ;
if ( $ dent and $ dent - > { value } )
{
push @ args , "-d" ;
2007-10-26 22:44:33 +00:00
$ dent - > { value } =~ s/\.$// ;
2008-10-10 14:03:34 +00:00
push @ args , $ dent - > { value } ;
2007-10-26 22:44:33 +00:00
}
}
2008-10-10 14:03:34 +00:00
unless ( grep /^-s$/ , @ args )
{
push @ args , "-s" ;
push @ args , $ Host ;
2007-10-26 22:44:33 +00:00
}
2008-10-10 14:03:34 +00:00
unless ( grep /^-n$/ , @ args )
{
2007-10-26 22:44:33 +00:00
my $ nettab = xCAT::Table - > new ( 'networks' ) ;
2008-10-10 14:03:34 +00:00
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 ( ) } )
{
push @ args , "-n" ;
push @ args , $ _ - > { net } . ":" . $ _ - > { mask } ;
2007-10-26 22:44:33 +00:00
}
}
2008-10-10 14:03:34 +00:00
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|
) ;
2008-10-13 14:42:44 +00:00
& PARSEARGS ( $ callback , @ args ) ;
2008-10-10 14:03:34 +00:00
& FIXUP ( $ callback ) ;
2008-10-13 14:42:44 +00:00
unless ( open ( HOSTS , $ Hostfile ) )
{
my $ rsp = { } ;
$ rsp - > { data } - > [ 0 ] = "Unable to open $Hostfile\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback , 1 ) ;
exit 1 ;
}
2008-10-10 14:03:34 +00:00
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]*$/ )
{
2007-10-26 22:44:33 +00:00
2008-10-10 14:03:34 +00:00
#$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 ;
}
2007-10-26 22:44:33 +00:00
2008-10-10 14:03:34 +00:00
# Match -e args
my $ netpat ;
foreach $ netpat ( @ elimpats )
{
next LINE if ( /[.\s]$netpat/ ) ;
}
2007-10-26 22:44:33 +00:00
2008-10-10 14:03:34 +00:00
# Process -c args
foreach $ netpat ( @ cpats )
{
if ( /\.$netpat/ )
{
( $ canonical , $ aliases ) = split ( ' ' , $ names , 2 ) ;
$ canonical =~ s/\.$netpat// ;
2009-05-07 17:24:13 +00:00
#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 ;
}
2008-10-10 14:03:34 +00:00
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
2009-05-07 17:24:13 +00:00
unless ( $ canonical =~ /^[a-z0-9-]+$/i ) {
xCAT::MsgUtils - > message ( "E" , { errorcode = > [ 1 ] , error = > [ "$canonical contains invalid characters, skipping entry" ] } , $ callback , 1 ) ;
next ;
}
2008-10-10 14:03:34 +00:00
$ 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 ;
2007-10-26 22:44:33 +00:00
}
2008-10-10 14:03:34 +00:00
#
# 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 )
{
2007-10-26 22:44:33 +00:00
#
2008-10-10 14:03:34 +00:00
# Skip over the alias if the alias and canonical
# name only differ in that one of them has the
# domain appended to it.
2007-10-26 22:44:33 +00:00
#
2008-10-10 14:03:34 +00:00
next
if ( $ dontdodomains && $ alias =~ /\./ ) ; # skip domain names
$ alias =~ s/$Domainpattern// ;
if ( $ alias eq $ canonical )
{
next ;
}
2009-05-07 17:24:13 +00:00
unless ( $ alias =~ /^[a-z0-9-]+$/i ) {
xCAT::MsgUtils - > message ( "E" , { errorcode = > [ 1 ] , error = > [ "$canonical alias $alias contains invalid characters, skipping entry" ] } , $ callback , 1 ) ;
next ;
}
2008-10-10 14:03:34 +00:00
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 ;
}
2007-10-26 22:44:33 +00:00
}
}
2008-10-10 14:03:34 +00:00
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// ;
}
2007-10-26 22:44:33 +00:00
}
}
2008-10-10 14:03:34 +00:00
}
}
if ( $ domx )
{
& MX ( $ callback , $ canonical , @ addrs ) ;
}
if ( $ dotxt )
{
& TXT ( $ canonical , @ addrs ) ;
}
if ( $ Commentfile ne "" )
{
2008-10-13 14:42:44 +00:00
& DO_COMMENTS ( $ callback , $ canonical , @ addrs ) ;
2008-10-10 14:03:34 +00:00
}
2007-10-26 22:44:33 +00:00
}
2008-10-10 14:03:34 +00:00
# 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" ;
}
2007-10-26 22:44:33 +00:00
}
2008-10-10 14:03:34 +00:00
# generate boot.* files
& GEN_BOOT ( $ callback ) ;
2008-10-13 14:42:44 +00:00
my $ rsp = { } ;
$ rsp - > { data } - > [ 0 ] = "Setup of DNS complete." ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ callback ) ;
exit 0 ;
2007-10-26 22:44:33 +00:00
}
#
# Generate resource record data for
# strings from the commment field that
# are found in the comment file (-C).
#
2008-10-10 14:03:34 +00:00
sub DO_COMMENTS
{
2008-10-13 14:42:44 +00:00
my ( $ callback , $ canonical , @ addrs ) = @ _ ;
2008-07-18 22:21:52 +00:00
my ( @ c , $ c , $ a , $ comments ) ;
2008-07-01 16:22:09 +00:00
2008-10-10 14:03:34 +00:00
if ( ! $ Commentfileread )
{
2008-10-13 14:42:44 +00:00
unless ( open ( F , $ Commentfile ) )
{
my $ rsp = { } ;
$ rsp - > { data } - > [ 0 ] = "Unable to open file $Commentfile: $!.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback , 1 ) ;
exit 1 ;
}
2008-10-10 14:03:34 +00:00
$ Commentfileread + + ;
while ( <F> )
{
chop ;
my ( $ key , $ c ) = split ( ':' , $ _ , 2 ) ;
$ CommentRRs { $ key } = $ c ;
}
close ( F ) ;
2007-10-26 22:44:33 +00:00
}
2008-07-01 16:22:09 +00:00
2008-07-18 22:21:52 +00:00
my $ key ;
2008-10-10 14:03:34 +00:00
foreach $ a ( @ addrs )
{
$ key = "$canonical-$a" ;
$ comments . = " $Comments{$key}" ;
2007-10-26 22:44:33 +00:00
}
@ c = split ( ' ' , $ comments ) ;
2008-10-10 14:03:34 +00:00
foreach $ c ( @ c )
{
if ( $ CommentRRs { $ c } )
{
printf DOMAIN "%-20s %s\n" , $ canonical , $ CommentRRs { $ c } ;
}
2007-10-26 22:44:33 +00:00
}
}
#
# Generate MX record data
#
2008-10-10 14:03:34 +00:00
sub MX
{
my ( $ callback , $ canonical , @ addrs ) = @ _ ;
2008-07-18 22:21:52 +00:00
my ( $ first , $ a , $ key , $ comments ) ;
2007-10-26 22:44:33 +00:00
2008-10-10 14:03:34 +00:00
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 ;
2007-10-26 22:44:33 +00:00
}
$ first = 1 ;
2008-10-10 14:03:34 +00:00
foreach $ a ( @ addrs )
{
$ key = "$canonical-$a" ;
$ comments . = " $Comments{$key}" ;
2007-10-26 22:44:33 +00:00
}
2008-07-01 16:22:09 +00:00
2008-10-10 14:03:34 +00:00
if ( $ comments !~ /\[no smtp\]/ )
{
2007-10-26 22:44:33 +00:00
# Add WKS if requested
2008-10-10 14:03:34 +00:00
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 ;
2007-10-26 22:44:33 +00:00
}
2008-10-10 14:03:34 +00:00
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 ;
}
}
2007-10-26 22:44:33 +00:00
}
}
#
# Generate TXT record data
#
2008-10-10 14:03:34 +00:00
sub TXT
{
2008-07-18 22:21:52 +00:00
my ( $ canonical , @ addrs ) = @ _ ;
my ( $ a , $ key , $ comments ) ;
2007-10-26 22:44:33 +00:00
2008-10-10 14:03:34 +00:00
foreach $ a ( @ addrs )
{
$ key = "$canonical-$a" ;
$ comments . = " $Comments{$key}" ;
2007-10-26 22:44:33 +00:00
}
$ comments =~ s/\[no smtp\]//g ;
$ comments =~ s/^\s*// ;
$ comments =~ s/\s*$// ;
2008-07-01 16:22:09 +00:00
2008-10-10 14:03:34 +00:00
if ( $ comments ne "" )
{
printf DOMAIN "%s IN TXT \"%s\"\n" , $ canonical , $ comments ;
2007-10-26 22:44:33 +00:00
}
}
#
# Create the SOA record at the beginning of the file
#
2008-10-10 14:03:34 +00:00
sub MAKE_SOA
{
my ( $ callback , $ fname , $ file ) = @ _ ;
2008-07-18 22:21:52 +00:00
my ( $ s ) ;
2007-10-26 22:44:33 +00:00
2008-10-10 14:03:34 +00:00
if ( - s $ fname )
{
2008-10-13 14:42:44 +00:00
unless ( open ( $ file , "$fname" ) )
{
my $ rsp = { } ;
$ rsp - > { data } - > [ 0 ] = "Unable to open $fname: $!.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback , 1 ) ;
exit 1 ;
}
2008-10-10 14:03:34 +00:00
$ _ = <$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 ) )
{
2007-10-26 22:44:33 +00:00
$ Serial = $ DateSerial ;
}
2008-10-10 14:03:34 +00:00
}
( $ 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 ) )
{
2007-10-26 22:44:33 +00:00
$ Serial = $ DateSerial ;
}
2008-10-10 14:03:34 +00:00
}
$ 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 ) )
{
2007-10-26 22:44:33 +00:00
$ Serial = $ DateSerial ;
}
2008-10-10 14:03:34 +00:00
}
$ Refresh = $ DefRefresh ;
$ Retry = $ DefRetry ;
$ Expire = $ DefExpire ;
$ Ttl = $ DefTtl ;
close ( $ file ) ;
2007-10-26 22:44:33 +00:00
}
2008-10-13 14:42:44 +00:00
unless ( open ( $ file , "> $fname" ) )
{
my $ rsp = { } ;
$ rsp - > { data } - > [ 0 ] = "Unable to open $fname: $!.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback , 1 ) ;
exit 1 ;
}
2008-10-10 14:03:34 +00:00
print $ file '$TTL 86400' . "\n" ;
2007-10-26 22:44:33 +00:00
print $ file "\@ IN SOA $RespHost $RespUser " ;
print $ file "( $Serial $Refresh $Retry $Expire $Ttl )\n" ;
2008-10-10 14:03:34 +00:00
foreach $ s ( @ Servers )
{
print $ file " IN NS $s\n" ;
2007-10-26 22:44:33 +00:00
}
print $ file "\n" ;
}
#
# Reverse the octets of an IP address and append
# in-addr.arpa.
#
2008-10-10 14:03:34 +00:00
sub REVERSE
{
2007-10-26 22:44:33 +00:00
join ( '.' , reverse ( split ( '\.' , $ _ [ 0 ] ) ) ) . '.IN-ADDR.ARPA.' ;
}
#
# Establish what we will be using for SOA records
#
2008-10-10 14:03:34 +00:00
sub FIXUP
{
my $ callback = shift ;
2008-07-18 22:21:52 +00:00
my ( $ s ) ;
2007-10-26 22:44:33 +00:00
2008-10-10 14:03:34 +00:00
if ( $ Host =~ /\./ )
{
$ RespHost = "$Host." ;
}
else
{
$ RespHost = "$Host.$Domain." ;
2007-10-26 22:44:33 +00:00
}
$ RespHost =~ s/\.\././g ;
2008-10-10 14:03:34 +00:00
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
2007-10-26 22:44:33 +00:00
}
2008-10-10 14:03:34 +00:00
else
{
$ RespUser = "$User.$RespHost" ; # -u user
}
$ RespUser =~ s/\.\././g ; # Strip any ".."'s to "."
2007-10-26 22:44:33 +00:00
# Clean up nameservers
2008-10-10 14:03:34 +00:00
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 . = "." ;
}
}
2007-10-26 22:44:33 +00:00
}
# Clean up MX hosts
2008-10-10 14:03:34 +00:00
foreach $ s ( @ Mx )
{
$ s =~ s/:/ / ;
if ( $ s !~ /\./ )
{
$ s . = ".$Domain" ;
}
if ( $ s !~ /\.$/ )
{
$ s . = "." ;
}
2007-10-26 22:44:33 +00:00
}
2008-10-09 18:15:08 +00:00
# Now open boot file (named.conf) and print saved data
2008-10-13 14:42:44 +00:00
unless ( open ( BOOT , "> $Bootfile" ) )
{
my $ rsp = { } ;
$ rsp - > { data } - > [ 0 ] = "Unable to open $Bootfile.\n" ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback , 1 ) ;
exit 1 ;
}
2007-10-26 22:44:33 +00:00
#
2008-07-01 16:22:09 +00:00
# Write either the version 4 boot file directives or the
2007-10-26 22:44:33 +00:00
# version 8 boot file directives.
#
2008-10-10 14:03:34 +00:00
if ( $ Version == 4 )
{
2007-10-26 22:44:33 +00:00
print BOOT "\ndirectory $DBDir\n" ;
2008-10-10 14:03:34 +00:00
foreach my $ line ( @ bootmsgs_v4 )
{
print BOOT $ line ;
2007-10-26 22:44:33 +00:00
}
print BOOT "cache\t. db.cache\n" ;
2008-10-10 14:03:34 +00:00
if ( - r "spcl.boot" )
{
2007-10-26 22:44:33 +00:00
print BOOT "include\tspcl.boot\n" ;
}
2008-10-10 14:03:34 +00:00
}
else
{
print BOOT qq|\noptions {\n\tdirectory "$DBDir";\n| ;
if ( @ forwarders )
{
2007-10-31 14:39:10 +00:00
print BOOT qq|\tforwarders {\n| ;
2008-10-10 14:03:34 +00:00
foreach ( @ forwarders )
{
2007-10-31 14:39:10 +00:00
print BOOT qq|\t\t$_;\n| ;
}
print BOOT qq|\t};\n| ;
2008-10-10 14:03:34 +00:00
}
if ( - r "spcl.options" )
{
2007-10-26 22:44:33 +00:00
print BOOT "\t# These options came from the file spcl.options\n" ;
2008-10-10 14:03:34 +00:00
2007-10-26 22:44:33 +00:00
#
2008-10-10 14:03:34 +00:00
# Copy the options in since "include" cannot be used
2007-10-26 22:44:33 +00:00
# within a statement.
#
2008-10-13 14:42:44 +00:00
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 ;
}
2008-10-10 14:03:34 +00:00
while ( <OPTIONS> )
2007-10-26 22:44:33 +00:00
{
print BOOT ;
}
close ( OPTIONS ) ;
}
print BOOT qq|};\n\n| ;
2008-10-10 14:03:34 +00:00
foreach my $ line ( @ bootmsgs_v8 )
{
print BOOT $ line ;
2007-10-26 22:44:33 +00:00
}
2010-09-20 10:32:39 +00:00
# hint zone is also needed for DNS forwarders on AIX
if ( xCAT::Utils - > isAIX ( ) )
2008-10-10 14:03:34 +00:00
{
print BOOT
qq|zone "." in {\n\ttype hint;\n\tfile "db.cache";\n};\n\n| ;
2007-10-31 14:39:10 +00:00
}
2010-09-20 10:32:39 +00:00
else
{
unless ( @ forwarders )
{
print BOOT
qq|zone "." in {\n\ttype hint;\n\tfile "db.cache";\n};\n\n| ;
}
}
2008-10-10 14:03:34 +00:00
if ( - r "spcl.boot" )
{
2007-10-26 22:44:33 +00:00
print BOOT qq|include "spcl.boot";\n\n| ;
}
}
2010-09-20 10:32:39 +00:00
close ( BOOT ) ;
2007-10-26 22:44:33 +00:00
# Go ahead and start creating files and making SOA's
2008-07-18 22:21:52 +00:00
my $ x1 ;
my $ x2 ;
2008-10-10 14:03:34 +00:00
foreach my $ i ( @ makesoa )
{
( $ x1 , $ x2 ) = split ( ' ' , $ i ) ;
& MAKE_SOA ( $ callback , $ x1 , $ x2 ) ;
2007-10-26 22:44:33 +00:00
}
printf DOMAIN "%-20s IN A 127.0.0.1\n" , "localhost" ;
2008-07-01 16:22:09 +00:00
2008-07-18 22:21:52 +00:00
my $ file = "DB.127.0.0.1" ;
2008-10-10 14:03:34 +00:00
& MAKE_SOA ( $ callback , $ DBDir . "db.127.0.0" , $ file ) ;
2010-09-20 10:32:39 +00:00
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" ;
2010-09-21 01:52:08 +00:00
my $ cmd = qq~dig @"$forwarders[0]" . ns >> $tmpfile~ ;
2010-09-20 10:32:39 +00:00
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" ) ;
2010-09-21 01:52:08 +00:00
close ( $ nothing ) ;
2010-09-20 10:32:39 +00:00
}
}
else
{
my $ nothing ;
open ( $ nothing , ">>" , $ DBDir . "db.cache" ) ;
2010-09-21 01:52:08 +00:00
close ( $ nothing ) ;
2010-09-20 10:32:39 +00:00
}
2007-10-26 22:44:33 +00:00
printf $ file "%-30s\tIN PTR localhost.\n" , & REVERSE ( "127.0.0.1" ) ;
close ( $ file ) ;
}
2008-10-10 14:03:34 +00:00
sub PARSEARGS
{
2008-10-13 14:42:44 +00:00
my ( $ callback , @ args ) = @ _ ;
2008-07-18 22:21:52 +00:00
my ( $ i , $ net , $ subnetmask , $ option , $ tmp1 ) ;
my ( $ file , @ newargs , @ targs ) ;
2008-10-10 14:03:34 +00:00
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 ) ;
2007-10-26 22:44:33 +00:00
$ i = 0 ;
2008-10-10 14:03:34 +00:00
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 ] ;
2008-10-13 14:42:44 +00:00
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 ;
}
2008-10-10 14:03:34 +00:00
while ( <F> )
{
next if ( /^#/ ) ;
next if ( /^$/ ) ;
chop ;
@ targs = split ( ' ' ) ;
push ( @ newargs , @ targs ) ;
2007-10-26 22:44:33 +00:00
}
2008-10-10 14:03:34 +00:00
close ( F ) ;
2008-10-13 14:42:44 +00:00
& PARSEARGS ( $ callback , @ newargs ) ;
2008-10-10 14:03:34 +00:00
}
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 ) ;
2007-10-26 22:44:33 +00:00
}
2008-10-10 14:03:34 +00:00
( $ DefRefresh , $ DefRetry , $ DefExpire , $ DefTtl ) =
split ( ':' , $ args [ $ i ] ) ;
2007-10-26 22:44:33 +00:00
$ UseDefSOAValues = 1 ;
2008-10-10 14:03:34 +00:00
}
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 + + ;
2007-10-26 22:44:33 +00:00
}
2008-07-01 16:22:09 +00:00
2008-10-10 14:03:34 +00:00
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 ) ;
2007-10-26 22:44:33 +00:00
}
}
2008-10-10 14:03:34 +00:00
sub BUILDNET
{
2008-07-18 22:21:52 +00:00
my ( $ net ) = @ _ ;
2007-10-26 22:44:33 +00:00
push ( @ Networks , $ net ) ;
2008-10-10 14:03:34 +00:00
2007-10-26 22:44:33 +00:00
#
2008-07-01 16:22:09 +00:00
# Create pattern to match against.
# The dots must be changed to \. so they
2007-10-26 22:44:33 +00:00
# aren't used as wildcards.
#
2008-07-18 22:21:52 +00:00
my $ netpat = $ net ;
2007-10-26 22:44:33 +00:00
$ netpat =~ s/\./\\./g ;
push ( @ Netpatterns , $ netpat ) ;
#
# Create db files for PTR records.
# Save the file names in an array for future use.
#
2008-07-18 22:21:52 +00:00
my $ netfile = "DB.$net" ;
2007-10-26 22:44:33 +00:00
$ Netfiles { $ netpat } = $ netfile ;
2008-10-10 14:03:34 +00:00
push ( @ makesoa , $ DBDir . "db.$net $netfile" ) ;
2007-10-26 22:44:33 +00:00
# Add entry to the boot file.
2008-07-18 22:21:52 +00:00
my $ revaddr = & REVERSE ( $ net ) ;
2008-10-10 14:03:34 +00:00
chop ( $ revaddr ) ; # remove trailing dot
2007-10-26 22:44:33 +00:00
push ( @ bootmsgs_v4 , "primary $revaddr db.$net\n" ) ;
2008-07-01 16:22:09 +00:00
push ( @ bootmsgs_v8 ,
2007-10-26 22:44:33 +00:00
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.
#
2008-10-10 14:03:34 +00:00
sub SUBNETS
{
2008-07-18 22:21:52 +00:00
my ( $ network , $ mask ) = @ _ ;
my ( @ ans , @ net , @ mask , $ buf , $ number , $ i , $ j , $ howmany ) ;
2007-10-26 22:44:33 +00:00
2008-10-10 14:03:34 +00:00
@ net = split ( /\./ , $ network ) ;
2007-10-26 22:44:33 +00:00
@ mask = split ( /\./ , $ mask ) ;
$ number = '' ;
2008-10-10 14:03:34 +00:00
2007-10-26 22:44:33 +00:00
#
# Only expand bytes 1, 2, or 3
# for DNS purposes
#
2008-10-10 14:03:34 +00:00
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 ;
}
2007-10-26 22:44:33 +00:00
}
2008-10-10 14:03:34 +00:00
if ( $# ans == - 1 )
{
push ( @ ans , $ network ) ;
2007-10-26 22:44:33 +00:00
}
2008-07-01 16:22:09 +00:00
2007-10-26 22:44:33 +00:00
@ ans ;
}
2008-10-10 14:03:34 +00:00
sub GEN_BOOT
{
2008-10-13 14:42:44 +00:00
$ callback = shift ;
2008-07-18 22:21:52 +00:00
my ( $ revaddr , $ n ) ;
2007-10-26 22:44:33 +00:00
2008-10-10 14:03:34 +00:00
if ( 0 )
{ #! -e "boot.cacheonly") { DISABLE THIS PART
#
# Create a boot file for a cache-only server
#
2008-10-13 14:42:44 +00:00
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 ;
}
2008-10-10 14:03:34 +00:00
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" )
{
2007-10-26 22:44:33 +00:00
printf F "include\t\tspcl.cacheonly\n" ;
}
2008-10-10 14:03:34 +00:00
close ( F ) ;
}
else
{
2007-10-26 22:44:33 +00:00
print F qq|\noptions {\n\tdirectory "$DBDir";\n| ;
2008-10-10 14:03:34 +00:00
if ( @ forwarders )
{
2007-10-26 22:44:33 +00:00
print F qq|\tforwarders {\n| ;
2008-10-10 14:03:34 +00:00
foreach ( @ forwarders )
{
2007-10-26 22:44:33 +00:00
print F qq|\t\t$_;\n| ;
}
print F qq|\t};\n| ;
}
2008-10-10 14:03:34 +00:00
if ( - r "spcl.options" )
{
2007-10-26 22:44:33 +00:00
print F "\t# These options came from the file spcl.options\n" ;
2008-10-10 14:03:34 +00:00
2007-10-26 22:44:33 +00:00
#
2008-10-10 14:03:34 +00:00
# Copy the options in since "include" cannot be used
2007-10-26 22:44:33 +00:00
# within a statement.
#
2008-10-10 14:03:34 +00:00
2008-10-13 14:42:44 +00:00
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 ;
}
2008-10-10 14:03:34 +00:00
while ( <OPTIONS> )
2007-10-26 22:44:33 +00:00
{
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| ;
2008-10-10 14:03:34 +00:00
2007-10-26 22:44:33 +00:00
#print F qq|zone "." in {\n\ttype hint;\n\tfile "db.cache";\n};\n\n|;
2008-10-10 14:03:34 +00:00
if ( - r "spcl.cacheonly" )
{
2007-10-26 22:44:33 +00:00
print F qq|include "spcl.cacheonly";\n\n| ;
}
}
}
2008-07-01 16:22:09 +00:00
2007-10-26 22:44:33 +00:00
#
# 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.
#
2008-10-10 14:03:34 +00:00
if ( defined ( $ Bootsecaddr ) )
{
2008-10-13 14:42:44 +00:00
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 ;
}
2008-10-10 14:03:34 +00:00
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 ;
2007-10-26 22:44:33 +00:00
}
2008-10-10 14:03:34 +00:00
print F "cache\t\t. db.cache\n" ;
if ( - r "spcl.boot" )
{
2007-10-26 22:44:33 +00:00
printf F "include\t\tspcl.boot\n" ;
}
2008-10-10 14:03:34 +00:00
}
else
{
2007-10-26 22:44:33 +00:00
print F qq|\noptions {\n\tdirectory "$DBDir";\n| ;
2008-10-10 14:03:34 +00:00
if ( - r "spcl.options" )
{
2007-10-26 22:44:33 +00:00
print F "\t# These options came from the file spcl.options\n" ;
2008-10-10 14:03:34 +00:00
2007-10-26 22:44:33 +00:00
#
2008-10-10 14:03:34 +00:00
# Copy the options in since "include" cannot be used
2007-10-26 22:44:33 +00:00
# within a statement.
#
2008-10-13 14:42:44 +00:00
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 ;
}
2008-10-10 14:03:34 +00:00
while ( <OPTIONS> )
2007-10-26 22:44:33 +00:00
{
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| ;
2008-10-10 14:03:34 +00:00
foreach $ n ( @ Networks )
{
$ revaddr = & REVERSE ( $ n ) ;
chop ( $ revaddr ) ;
2007-10-26 22:44:33 +00:00
print F qq|zone "$revaddr" in {\n\ttype slave;\n\tmasters {| ;
print F qq| $Bootsecaddr; };\n};\n\n| ;
}
2008-10-10 14:03:34 +00:00
2007-10-26 22:44:33 +00:00
#print F qq|zone "." in {\n\ttype hint;\n\tfile "db.cache";\n};\n\n|;
2008-10-10 14:03:34 +00:00
if ( - r "spcl.boot" )
{
2007-10-26 22:44:33 +00:00
print F qq|include "spcl.boot";\n\n| ;
}
}
2008-10-10 14:03:34 +00:00
close ( F ) ;
2008-10-13 14:42:44 +00:00
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 ;
}
2008-10-10 14:03:34 +00:00
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" )
{
2007-10-26 22:44:33 +00:00
printf F "include\t\tspcl.boot\n" ;
}
2008-10-10 14:03:34 +00:00
}
else
{
print F qq|\noptions {\n\tdirectory "$DBDir";\n| ;
if ( - r "spcl.options" )
{
2007-10-26 22:44:33 +00:00
print F "\t# These options came from the file spcl.options\n" ;
2008-10-10 14:03:34 +00:00
2007-10-26 22:44:33 +00:00
#
2008-10-10 14:03:34 +00:00
# Copy the options in since "include" cannot be used
2007-10-26 22:44:33 +00:00
# within a statement.
#
2008-10-13 14:42:44 +00:00
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 ;
}
2008-10-10 14:03:34 +00:00
while ( <OPTIONS> )
2007-10-26 22:44:33 +00:00
{
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| ;
2008-10-10 14:03:34 +00:00
print F
qq|zone "$Domain" in {\n\ttype slave;\n\tfile "db.$Domainfile";| ;
2007-10-26 22:44:33 +00:00
print F qq|\n\tmasters { $Bootsecsaveaddr; };\n};\n\n| ;
2008-10-10 14:03:34 +00:00
foreach $ n ( @ Networks )
{
$ revaddr = & REVERSE ( $ n ) ;
chop ( $ revaddr ) ;
2008-07-01 16:22:09 +00:00
print F
2008-10-10 14:03:34 +00:00
qq|zone "$revaddr" in {\n\ttype slave;\n\tfile "db.$n";\n\tmasters {| ;
2007-10-26 22:44:33 +00:00
print F qq| $Bootsecsaveaddr; };\n};\n\n| ;
}
#print F qq|zone "." in {\n\ttype hint;\n\tfile "db.cache";\n};\n\n|;
2008-10-10 14:03:34 +00:00
if ( - r "spcl.boot" )
{
2007-10-26 22:44:33 +00:00
print F qq|include "spcl.boot";\n\n| ;
}
}
2008-10-10 14:03:34 +00:00
close ( F ) ;
2007-10-26 22:44:33 +00:00
}
}
2008-10-10 14:03:34 +00:00
2008-10-09 18:15:08 +00:00
# subroutine to display the usage
sub checkusageandversion
{
2008-10-10 14:03:34 +00:00
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 ;
2008-10-09 18:15:08 +00:00
}
2007-10-26 22:44:33 +00:00
1 ;