pf-tools commit: r442 [ccaillet-guest] - in /trunk/sbin: ./ mk_dhcp mk_interfaces mk_packages mk_privatezone mk_pxelinuxcfg mk_resolvconf mkrdns update-config update-links

parmelan-guest at users.alioth.debian.org parmelan-guest at users.alioth.debian.org
Mon Mar 5 15:18:47 CET 2007


Author: ccaillet-guest
Date: Mon Mar  5 14:18:46 2007
New Revision: 442

URL: http://svn.debian.org/wsvn/pf-tools/?sc=1&rev=442
Log:
ADD:
  * adding some tools extract from root directory and modify for using PFTools::<modules>

WARNING :
  * no functional tests are performed a simple perl -cw <tools> is made
  * It is a WORK IN PROGRESS and intermediary commit for backuping mods


Added:
    trunk/sbin/
    trunk/sbin/mk_dhcp   (with props)
    trunk/sbin/mk_interfaces   (with props)
    trunk/sbin/mk_packages   (with props)
    trunk/sbin/mk_privatezone   (with props)
    trunk/sbin/mk_pxelinuxcfg   (with props)
    trunk/sbin/mk_resolvconf   (with props)
    trunk/sbin/mkrdns   (with props)
    trunk/sbin/update-config   (with props)
    trunk/sbin/update-links   (with props)

Added: trunk/sbin/mk_dhcp
URL: http://svn.debian.org/wsvn/pf-tools/trunk/sbin/mk_dhcp?rev=442&op=file
==============================================================================
--- trunk/sbin/mk_dhcp (added)
+++ trunk/sbin/mk_dhcp Mon Mar  5 14:18:46 2007
@@ -1,0 +1,52 @@
+#!/usr/bin/perl -w
+##
+##  $Id$
+##
+##  Copyright (C) 2005 Olivier MOLTENI <olivier at molteni.net>
+##
+##  This program is free software; you can 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
+##  of the License, or (at your option) any later version.
+##
+##  This program 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.
+##
+##  You should have received a copy of the GNU General Public License
+##  along with this program; if not, write to the Free Software
+##  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+##
+
+#use strict;
+use warnings;
+
+# Librairies
+#------------------
+use PFTools::Net ;
+use PFTools::Update ;
+
+# Globales
+#-------------
+
+if ( $#ARGV != 2 ) {
+    print STDERR "Usage: $0 head src dest\n";
+
+    #exit 1;
+}
+
+my ( $HEAD, $SRC, $DST ) = @ARGV;
+
+# compat mode
+if ( !defined $DST ) {
+    $HEAD = "/etc/dhcpd.conf.head";
+    $SRC  = "GLOBAL:private-network";
+    $DST  = "/etc/dhcpd.conf";
+}
+
+# Generation de la zone
+#-------------------------
+
+Mk_dhcp( Get_source($HEAD), $DST, Init_lib_net( Get_source($SRC) ) );
+

Propchange: trunk/sbin/mk_dhcp
------------------------------------------------------------------------------
    svn:executable = *

Added: trunk/sbin/mk_interfaces
URL: http://svn.debian.org/wsvn/pf-tools/trunk/sbin/mk_interfaces?rev=442&op=file
==============================================================================
--- trunk/sbin/mk_interfaces (added)
+++ trunk/sbin/mk_interfaces Mon Mar  5 14:18:46 2007
@@ -1,0 +1,34 @@
+#!/usr/bin/perl -w
+##
+##  $Id$
+##
+##  Copyright (C) 2005 Olivier MOLTENI <olivier at molteni.net>
+##
+##  This program is free software; you can 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
+##  of the License, or (at your option) any later version.
+##
+##  This program 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.
+##
+##  You should have received a copy of the GNU General Public License
+##  along with this program; if not, write to the Free Software
+##  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+##
+
+#use strict;
+use warnings;
+
+use PFTools::Net ;
+
+if ( $#ARGV != 2 ) {
+    print STDERR "Usage: $0 config host dest\n";
+    exit 1;
+}
+
+my ( $config, $host, $dst ) = @ARGV;
+Mk_interfaces( $host, $dst, Init_lib_net( Get_source($config) ) );
+

Propchange: trunk/sbin/mk_interfaces
------------------------------------------------------------------------------
    svn:executable = *

Added: trunk/sbin/mk_packages
URL: http://svn.debian.org/wsvn/pf-tools/trunk/sbin/mk_packages?rev=442&op=file
==============================================================================
--- trunk/sbin/mk_packages (added)
+++ trunk/sbin/mk_packages Mon Mar  5 14:18:46 2007
@@ -1,0 +1,65 @@
+#!/usr/bin/perl
+##
+##  $Id$
+##
+##  Copyright (C) 2005 Olivier MOLTENI <olivier at molteni.net>
+##
+##  This program is free software; you can 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
+##  of the License, or (at your option) any later version.
+##
+##  This program 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.
+##
+##  You should have received a copy of the GNU General Public License
+##  along with this program; if not, write to the Free Software
+##  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+##
+
+if ( system("gzip -dc $ARGV[0] >/dev/null 2>&1") ) {
+    print "Usage: $0 <Path/packages.gz>\n";
+    exit 1;
+}
+
+$Packages = shift (@ARGV);
+system("mv $Packages $Packages.old");
+open( PACKAGES, "| gzip -c > $Packages" );
+$Packages =~ s:/[^/]+$::;
+
+foreach (`find $Packages -name '*.deb' -type f 2>/dev/null`) {
+    chomp( $pkg = $_ );
+    @PKG_INFOS = `dpkg -f $pkg 2>/dev/null`;
+    if ( !$? ) {
+
+        #print "Traitement de $pkg ...\n" ;
+        $sz = -s $pkg;
+        $pkg =~ s:^.*debian/::;
+
+        foreach (@PKG_INFOS) {
+            if (/^Description:/) {
+                print PACKAGES "Size: $sz\n";
+                print PACKAGES "Filename: $pkg\n";
+            }
+            print PACKAGES;
+        }
+        print PACKAGES "\n";
+        $count++;
+    }
+    else {
+        print "**** Package $pkg corrompu !!\n";
+        $bad++;
+    }
+}
+close(PACKAGES);
+
+if ($bad) {
+    print "\n";
+}
+print "Successfully added $count packages.\n";
+if ($bad) {
+    print "Found $bad corrupted packages !!\n";
+}
+

Propchange: trunk/sbin/mk_packages
------------------------------------------------------------------------------
    svn:executable = *

Added: trunk/sbin/mk_privatezone
URL: http://svn.debian.org/wsvn/pf-tools/trunk/sbin/mk_privatezone?rev=442&op=file
==============================================================================
--- trunk/sbin/mk_privatezone (added)
+++ trunk/sbin/mk_privatezone Mon Mar  5 14:18:46 2007
@@ -1,0 +1,62 @@
+#!/usr/bin/perl -w
+##
+##  $Id$
+##
+##  Copyright (C) 2005 Olivier MOLTENI <olivier at molteni.net>
+##
+##  This program is free software; you can 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
+##  of the License, or (at your option) any later version.
+##
+##  This program 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.
+##
+##  You should have received a copy of the GNU General Public License
+##  along with this program; if not, write to the Free Software
+##  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+##
+
+#use strict;
+use warnings;
+
+# Librairies
+#------------------
+use PFTools::Net ;
+use PFTools::Update ;
+
+# Globales
+#-------------
+
+if ( $#ARGV < 1 ) {
+
+    print STDERR "Usage: $0 src forward\n";
+
+    #exit 1;
+}
+
+my ( $SRC, $FORWARD ) = @ARGV;
+shift @ARGV;
+shift @ARGV;
+
+# compat mode
+if ( !defined $FORWARD ) {
+    $SRC     = "CVS:config/GLOBAL/private-network";
+    $FORWARD = "/etc/bind/db.private";
+
+    #@ARGV    = ("/etc/bind/db.192.168");
+}
+
+# Generation de la zone
+#-------------------------
+
+$Z = Init_lib_net( Get_source($SRC) );
+Mk_zone( Get_source($FORWARD), $Z );
+
+#foreach $reverse (@ARGV) {
+#    Mk_zoneheader( Get_source($reverse), $Z );
+#}
+#system("mkrdns -quiet /etc/bind/named.conf");
+

Propchange: trunk/sbin/mk_privatezone
------------------------------------------------------------------------------
    svn:executable = *

Added: trunk/sbin/mk_pxelinuxcfg
URL: http://svn.debian.org/wsvn/pf-tools/trunk/sbin/mk_pxelinuxcfg?rev=442&op=file
==============================================================================
--- trunk/sbin/mk_pxelinuxcfg (added)
+++ trunk/sbin/mk_pxelinuxcfg Mon Mar  5 14:18:46 2007
@@ -1,0 +1,45 @@
+#!/usr/bin/perl -w
+##
+##  $Id$
+##
+##  Copyright (C) 2005 Olivier MOLTENI <olivier at molteni.net>
+##
+##  This program is free software; you can 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
+##  of the License, or (at your option) any later version.
+##
+##  This program 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.
+##
+##  You should have received a copy of the GNU General Public License
+##  along with this program; if not, write to the Free Software
+##  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+##
+
+#use strict;
+use warnings;
+
+# Librairies
+#------------------
+use PFTools::Net ;
+use PFTools::Update ;
+
+# Globales
+#-------------
+
+if ( $#ARGV != 1 ) {
+    print STDERR "Usage: $0 src template\n";
+    print STDERR "\t(confs will be written do template's dirname)\n";
+    exit 1;
+}
+
+my ( $SRC, $TEMPLATE ) = @ARGV;
+
+# Generation de la zone
+#-------------------------
+
+Mk_pxelinuxcfg( Get_source($TEMPLATE), Init_lib_net( Get_source($SRC) ) );
+

Propchange: trunk/sbin/mk_pxelinuxcfg
------------------------------------------------------------------------------
    svn:executable = *

Added: trunk/sbin/mk_resolvconf
URL: http://svn.debian.org/wsvn/pf-tools/trunk/sbin/mk_resolvconf?rev=442&op=file
==============================================================================
--- trunk/sbin/mk_resolvconf (added)
+++ trunk/sbin/mk_resolvconf Mon Mar  5 14:18:46 2007
@@ -1,0 +1,47 @@
+#!/usr/bin/perl -w
+##
+##  $Id$
+##
+##  Copyright (C) 2005 Olivier MOLTENI <olivier at molteni.net>
+##
+##  This program is free software; you can 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
+##  of the License, or (at your option) any later version.
+##
+##  This program 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.
+##
+##  You should have received a copy of the GNU General Public License
+##  along with this program; if not, write to the Free Software
+##  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+##
+
+#use strict;
+use warnings;
+
+use PFTools::Net ;
+use PFTools::Update ;
+
+if ( $#ARGV != 2 ) {
+    print STDERR "Usage: $0 config host dest\n";
+    exit 1;
+}
+
+my ( $config, $host, $dst ) = @ARGV;
+my $Z   = Init_lib_net( Get_source($config) );
+my @dns = Get_dns_from_hostname( $Z, $host );
+
+open( OUT, ">$dst" ) || die;
+
+print OUT "search " . $Z->{SOA}->{name} . "\n";
+foreach $dns (@dns) {
+    if ( defined $dns ) {
+        print OUT "nameserver " . $dns . "\n";
+    }
+}
+
+close(OUT);
+

Propchange: trunk/sbin/mk_resolvconf
------------------------------------------------------------------------------
    svn:executable = *

Added: trunk/sbin/mkrdns
URL: http://svn.debian.org/wsvn/pf-tools/trunk/sbin/mkrdns?rev=442&op=file
==============================================================================
--- trunk/sbin/mkrdns (added)
+++ trunk/sbin/mkrdns Mon Mar  5 14:18:46 2007
@@ -1,0 +1,1191 @@
+#!/usr/bin/perl
+#
+# mkrdns - Make Reverse DNS - Version 3.3
+#
+# By: Theo Van Dinter (felicity at mkrdns.org) (c) 1998-2002
+# Revision Info: $Id: mkrdns 423 2006-03-15 11:04:45Z tom $
+#
+# The goal of this script is to automatically generate new reverse IP
+# mapping zone files for DNS/BIND.  It's been done before, but there
+# always seems to be something which makes it not workable in my
+# environment.  This script fixes that problem by adapting as necessary.
+#
+# Feel free to subscribe to the mkrdns mailing list.  Instructions are
+# available from the mkrdns web page: http://www.mkrdns.org/ The list is
+# available to discuss mkrdns-related topics (mkrdns, DNS, etc.) and is
+# also used to announce new versions of mkrdns.
+#
+#
+# This program is free software; you can 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 of the License, or (at your
+# option) any later version.
+#
+# This program 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+#
+
+use strict;
+use Getopt::Long;
+use POSIX qw(strftime);
+
+# User Specified variables (commandline)
+my ($debug)    = 0;      # display debugging information (user)
+my ($help)     = 0;      # help screen (user)
+my ($bootfile) = "";     # configuration file to use (user)
+my ($ext)      = "";     # extension for output files (user)
+my ($quiet)    = 0;      # show errors only, or warnings too?
+my ($version)  = 0;      # show version information
+my ($rootdir)  = "/";    # root directory for files
+
+# Program needed variables
+my ( $i, @domains, %networks, %maps, %serial, %mips, %hash, %netmap, @toskip );
+my ( %zonetoskip, $nameddir, %numordate, %files, $toskip, $ignoreslaves );
+my ($pversion)  = "3.3";
+my ($whichhash) = undef;    # which hash function to use
+
+# Get commandline parameters
+$i = &GetOptions(
+  "debug"       => \$debug,
+  "help|h"      => \$help,
+  "extension=s" => \$ext,
+  "quiet"       => \$quiet,
+  "version"     => \$version,
+  "rootdir=s"   => \$rootdir,
+  "hash=i"      => \$whichhash,
+  "<>"          => sub { $bootfile = $_[0] },    # any "non-option" is
+                                                 # config (boot) file
+);
+
+if ( $version || !$i || $help ) {
+  print "
+mkrdns v$pversion (c) 1998-2002
+By: Theo Van Dinter (felicity\@mkrdns.org)
+
+";
+
+  print "Usage: $0 [options] [configuration file]
+
+Options:
+-debug\t\tTurn on debugging (warning, this prints a *LOT* of info)
+-extension\tAppend given extension to output files
+-help\t\tShow this help screen
+-quiet\t\tTurn off warning messages (multiple A records -> IP, etc.)
+-rootdir\tSpecify the root directory that named will run in (chroot)
+-version\tShow the mkrdns version information
+
+Configuration file is the full path to either named.boot or named.conf.
+If not specified, mkrdns will search common locations for the files.
+
+" unless ($version);
+  exit 0;
+}
+
+warn "(warn) The --hash option is depricated, just using 32-bit CRC built-in.\n"
+  if ( defined $whichhash );
+
+if ( $ext =~ /^\./ ) {    # Remove the '.'s from the start of the extention ...
+  $ext =~ s/^\.+//;
+  warn "(warn) Extension started with '.' -- removed.  Extention now '$ext'.\n";
+}
+
+if ($debug) {
+  print "Debugging turned on.\n", "Version     = $pversion\n",
+'C. Revision = $Id: mkrdns 423 2006-03-15 11:04:45Z tom $',
+    "\n", "Help        = $help\n", "Quiet Mode  = $quiet\n",
+    "Root Dir    = $rootdir\n";
+  print "Extension   = $ext\n" if ($ext);
+  print "Hash Func   = 32-bit checksum\n";
+  print "\n";
+}
+
+$rootdir = &FixPath($rootdir);
+if ( $rootdir !~ m#^/# || $rootdir =~ m#^/?\.\.(/|$)# ) {
+  die qq{(fatal) Root directory ("$rootdir") is invalid.\n};
+}
+
+# If bootfile wasn't specified, try to find one in standard locations ...
+unless ($bootfile) {
+  my ($stdloc);
+  my (@locs) = qw{	/etc /var/named /usr/named /usr/local/etc
+    /usr/freeware/etc /etc/named /etc/bind };
+
+  warn
+"(warn) No configuration file specified.  Checking in standard locations ...\n";
+
+  foreach $stdloc (@locs) {
+    opendir( DIR, $stdloc ) || next;
+    my (@files) = grep( /^named\.(boot|conf)$/, readdir(DIR) );
+    closedir(DIR);
+
+    print "(debug) Config files found in $stdloc: ", join ( ",", @files ), "\n"
+      if ($debug);
+
+    if ( $#files == -1 ) {    # named.boot and named.conf weren't found, exit.
+      print
+        qq{(debug) Neither named.boot nor named.conf were found in "$stdloc".\n}
+        if ($debug);
+    }
+    elsif ( $#files == 0 ) {    # one file was found, use it.
+      $bootfile = "$stdloc/$files[0]";
+      warn "(info) $bootfile was found.\n";
+    }
+    else {    # more than one file was found, use the "best" one.
+      $bootfile = "$stdloc/named.conf";
+      warn "(info) Multiple configuration files were found, using $bootfile.\n";
+    }
+
+    last if ($bootfile);
+  }
+
+  die
+"(die) Couldn't find either named.boot or named.conf in any standard location.  Exiting.\n"
+    unless ($bootfile);
+}
+
+READCONF: {
+  my ($type) =
+    ( $bootfile =~ /\.(\w+)$/ );  # what kind of config file (boot, conf, etc.)?
+
+  # neither boot nor conf -- start crying and exit.
+  if ( $type !~ /^(boot|conf)$/ ) {
+    die "(fatal) $bootfile is neither a boot nor conf file.\n";
+  }
+
+  # Read configuration file into memory.
+  my ($config);
+  open( CONF, "<$bootfile" ) || die "(fatal) Can't open $bootfile:$!";
+  while ( $_ = <CONF> ) {         # deal with the includes!
+    if ( ( /^directory/i && $type eq "boot" )
+      || ( /\bdirectory\s+"[^"]+";/ && $type eq "conf" ) )
+    {
+      $nameddir = (m/\bdirectory\s+"?([^"\s]+)"?/i)[0];
+      print "(debug) Named Directory = $nameddir\n" if ($debug);
+    }
+
+    if ( ( /^\s*include\s/i && $type eq "boot" )
+      || ( /\binclude\s+"/i && $type eq "conf" ) )
+    {                             # include statement!
+      my (@conf) = ($_);
+
+      # (boot) ^include <file>
+      # (conf) ^include "<file>";
+      for ( my ($i) = 0 ; $i <= $#conf ; $i++ ) {
+        next
+          unless ( $conf[$i] =~ /\binclude\s/i );    # skip non includes ...
+        chomp $conf[$i];
+        print "(debug) Include statement ($conf[$i]) found.\n"
+          if ($debug);
+
+        my ($file) = ( $conf[$i] =~ m/\binclude\s+"?([^"\s]+)"?/i );
+        $file =~ s/\s+//;    # files shouldn't have whitespace ...
+        unless ( $file =~ m!^/! ) {    # relative
+          unless ($nameddir) {         # include before directory?  boo!
+            $nameddir = ".";
+            warn
+qq{(warn) Include found before named directory was specified!  Using ".".\n};
+          }
+          $file = "$nameddir/$file";
+        }
+
+        $file = &Handle_Path( $rootdir, $file );
+        print "(debug) Including file $file.\n" if ($debug);
+        open( IN, "<$file" ) || die "(fatal) Can't open $file:$!";
+        if ( $type eq "boot" ) {
+          splice @conf, $i--, 1,
+            <IN>;    # replace include with data then recheck index
+        }
+        elsif ( $type eq "conf" ) {
+          $conf[$i] =~ /^(.*)\binclude\s+"?[^"\s]+"?\;(.*)$/i;
+          splice @conf, $i--, 1, $1, <IN>, $2;
+        }
+        close(IN);
+      }
+
+      $config .= join ( "", @conf );    # tack in included stuff ...
+      next;
+    }
+
+    $config .= $_;                      # append single line!
+  }
+  close(CONF);
+  print "(debug) Read in $bootfile.\n" if ($debug);
+
+  # no directory statement anywhere?
+  die "(fatal) No named directory specified!\n" unless ($nameddir);
+
+  if ( $type eq "boot" ) {              # parse named.boot
+                                        # deal with directives
+    foreach ( grep( /^;\s*mkrdns\s+/, split ( /\n/, $config ) ) ) {
+      s/^;\s*mkrdns\s+//;
+      &Directives($_);
+    }
+
+    foreach $i ( split ( /\n/, $config ) ) {
+      $i =~ s/;.*$//;                   # remove comments
+      $i =~ s/^\s+//;                   # remove whitespace
+      $i =~ s/\s+$//;
+
+      if ( $i =~ /^(primary|secondary)/i ) {    # primary/secondary domain ...
+        my ( $type, $domain, $tmp, $file ) =
+          ( $i =~ /^(\S+)\s+(\S+)\s+(\S+\s+)?(\S+)\s*$/ );
+
+        &Handle_Domain( 'default', $type, $domain, $file, \%files );
+      }
+    }
+  }
+  elsif ( $type eq "conf" ) {                   # parse named.conf
+    my ($directives) = ( $config =~ m!^/\*\s*mkrdns(.+?)\*/!msi );
+
+    if ($directives) {                          # mkrdns directive
+      foreach $i ( split ( /\n/, $directives ) ) {
+        $i =~ s/\#.+$//;
+        $i =~ s/^\s+//;
+        $i =~ s/\s+$//;
+
+        next unless $i =~ /\S/;
+
+        &Directives($i);
+      }
+    }
+
+    # Remove comments from config!
+    $config =~ s!/\*.*?\*/!!gs;    # /* ... */
+    $config =~ s!//.*?\n!\n!gs;    # // ...
+    $config =~ s!\#.*?\n!\n!gs;    # # ...
+
+    # determine which domains and networks we are master for.
+
+    # Set the defaults
+    my $count = 0;
+    my $view  = "default";
+    my $views = undef;
+    my $zone  = undef;
+    my $type  = undef;
+    my $file  = undef;
+
+    # some people have whitespace between } and ;, so fix it...
+    $config =~ s/}\s+;/};/g;
+
+    # The controls { inet ... }; thing is the only one that
+    # doesn't have a }; at the end of one of the sections.
+    # That's very annoying, so we get rid of it all since we don't
+    # need it anyway.  The inet command is supposedly the only
+    # thing valid in the controls section, but there can multiple
+    # inet entries, so we remove them all.
+    $config =~ s/\bcontrols\s*{(?:\s*inet\b.+?};)+\s*};//s;
+
+    # Make sure that the { and }; are properly on their own.
+    $config =~ s/};/\n};/g;
+    $config =~ s/{/{\n/g;
+
+    # Each config line should be by itself for easier parsing
+    $config =~ s/\;/\;\n/g;
+
+    # Go through the input file!
+    foreach ( split ( /\n/, $config ) ) {
+      if (/\bview\s+"([^"]+)"/i) {    # If we see a view statement ...
+        $view = $1;                   # set the view
+
+        # Now figure out if the statement is valid or not.
+        if ( defined $views && $views == 0 ) {
+
+          # A view was defined after a non-viewed zone ...
+
+          die "Can't have non-zoned and zoned views!\n";
+        }
+        if ( $count > 0 ) {
+
+          # A view must not be enclosed in bracies.
+
+          die "Views must be defined at the top level (view $view).\n";
+        }
+
+        # We know that we're validly views now.
+        $views = 1 unless defined $views;
+      }
+      elsif (/\bzone\s+"([^"]+)"/i) {    # Now we see a zone statement ...
+        $zone = lc $1;                   # set the zone
+
+        # Now figure out if the statement is valid or not.
+        if ( defined $views && $views == 1 && $count < 1 ) {
+
+          # A zone must either be in a view or at the top level
+
+          die "Can't have non-zoned and zoned views!\n";
+        }
+        if ( $count > 1 ) {
+          die "Zones are not embedable (zone $zone is in another zone)!\n";
+        }
+
+        # If we're a zone and not in a view ...
+        # $views == $count so that we can verify the level we should
+        # be at for config options.
+        $views = $count unless defined $views;
+      }
+
+      # Re-calculate our config level
+      $count += /{/g;
+      $count -= /};/g;
+
+      # If there's a configuration file error and too many }; are found ...
+      die "Too many }; found!\n" if ( $count < 0 );
+
+      # Reset things if we've closed all our config levels out ...
+      $view = "default" if ( $count < 1 );
+      if ( !defined $views || $count <= $views ) {
+        if ( defined $zone && defined $type && !defined $file ) {
+          warn qq{(warn) No file specified for zone "$zone" in "$bootfile".\n};
+        }
+
+        $zone = undef;
+        $type = undef;
+        $file = undef;
+      }
+
+      next unless ( defined $zone );    # we need to be in a zone
+      next if ( $count != $views + 1 ); # we need to be at the right level
+      next unless /\b(type|file)\b/i;   # only use type and file
+
+      if (/\btype\s+(master|slave)\b/i) {
+        $type = lc $1;
+      }
+      if (/\bfile\s+"([^"]+)"/i) {
+        $file = $1;
+      }
+
+      next unless ( defined $type && defined $file );
+
+      Handle_Domain( $view, $type, $zone, $file, \%files );
+    }
+
+  }
+}
+
+# Take the array of regexps to skip and put them in a single var
+$toskip = @toskip ? join ( "|", @toskip ) : undef;
+
+# Read in current reverse maps, report errors.  Remember non-PTR lines
+# for creation later on.
+REVERSE: {
+  while ( my ( $view, $nets ) = each %networks ) {
+    while ( my ( $net, $file ) = each %{$nets} ) {
+      open( IN, "<$file" )
+        || die qq{(fatal) Can't open "$file" for reading:$!};
+      seek( IN, 0, 0 );
+      {
+        local $/ = undef;    # slurp mode
+        $hash{$file} = Do_Hash(<IN>); # get the hash value for the original file
+      }
+
+      print "(debug) Generated hash value for $file: $hash{$file}.\n"
+        if ($debug);
+
+      print "(debug) Scanning $file for non-PTR lines:\n" if ($debug);
+      seek( IN, 0, 0 );
+
+      # strip out PTR, $GENERATE, $ORIGIN, and $INCLUDE ...
+      $maps{$view}->{$net} =
+        join ( "", grep( !/(\s+PTR\s+|^\$(ORIGIN|INCLUDE|GENERATE))/i, <IN> ) );
+      close(IN);
+
+      # Pick out the serial number ( required to be the first RR,
+      # so the regexp is not too complex. )
+      ( $i = $maps{$view}->{$net} ) =~ s/\s*;.+?\n//g;    # remove comments
+      ( $serial{$file} ) = ( $i =~ m!\s+SOA\s+\S+\s+\S+\s+(?:\(\s*)?(\d+)!is );
+
+      if ($debug) {    # print out non-PTR records (long...?)
+        foreach $i (
+          split ( /\n/, $maps{$view}->{$net} ),
+          "Parsed serial number: $serial{$file}"
+          )
+        {
+          print "(debug) $i\n";
+        }
+      }
+    }
+  }
+}
+
+# Read in current forward maps, convert A records into PTR records,
+# add to map.  If there are multiple A records for a given IP, report
+# duplicate, and keep first.
+#
+# This routine is the biggest time suck...
+#
+READIN: {
+  foreach (@domains) {
+    my ( $view, $domain, $map ) =
+      split ( /:/, $_ );    # $view = view, $domain = domain, $map = map file
+    my ($last) = "$domain.";    # what to use in case of blank hostname
+                                # hostname, $ORIGIN, domain in that order
+    my ($end)  = $last;         # what to use in case of relative hostname
+                                # $ORIGIN then domain, in that order
+
+    print
+      "(debug) Reading in entries from $map for domain $domain, view $view.\n"
+      if ($debug);
+
+    my (@data);
+    open( IN, "<$map" ) || die "(fatal) Can't open $map:$!";
+    chomp( @data = <IN> );      # slurp in map file w/out ending \n's
+    close(IN);
+
+    # deal with $INCLUDE and $GENERATE statements ...
+    print "(debug) Scanning for \$INCLUDE and \$GENERATE statements...\n"
+      if ($debug);
+
+    for ( $i = 0 ; $i <= $#data ; $i++ ) {
+      next
+        unless ( $data[$i] =~ /^\$(INCLUDE|GENERATE)/ )
+        ;                       # skip non-include/generate lines
+
+      $data[$i] =~ s/;.*$//;    # remove comments & whitespace
+      $data[$i] =~ s/\s+$//;
+
+      if ( $data[$i] =~ /^\$GENERATE/ ) {
+        print qq{(debug) "$data[$i]" specified.\n} if ($debug);
+
+        # Set ORIGIN to blank -- we'll handle it later.
+        splice @data, $i, 1, &Handle_GENERATE( "", $data[$i] );
+      }
+      elsif ( $data[$i] =~ /^\$INCLUDE/ ) {
+
+        # $INCLUDE <file> <origin>
+        my ( $inc, $file, $origin ) = split ( /\s+/, $data[$i] );
+
+        print qq{(debug) "$data[$i]" specified.\n} if ($debug);
+
+        $file = "$nameddir/$file" unless ( $file =~ m!^/! );
+
+        $file = &Handle_Path( $rootdir, $file );
+        my (@inc);
+        open( IN, "<$file" )
+          || die qq{(fatal) Can't read \$INCLUDE file "$file":$!};
+        chomp( @inc = <IN> );
+        close(IN);
+
+        if ($origin) {    # specified origin applies only to specified
+                          # include file.  put appropriate sections at end
+                          # of zone file.  see BIND 3rd ed. p.146
+
+          # put $ORIGIN and included file at the end of the config
+          push ( @data, "\$ORIGIN $origin", @inc );
+          splice @data, $i, 1;    # remove $INCLUDE line
+        }
+        else {    # just replace the $INCLUDE line with the contents of file
+          splice @data, $i, 1, @inc;
+        }
+        $i--;     # rescan the line where the $INCLUDE was.
+      }
+    }
+
+    # the file should be fully expanded in memory now.
+    # go through all 'host ? ? ?' and $ORIGIN lines ...
+    foreach $i ( grep( /^(\S*(\s+\d+)?(\s+\w+)?\s+\S+\s+|\$ORIGIN)/i, @data ) )
+    {
+      $i =~ s/\s*;.*$//;    # strip comments ...
+      next unless ( length $i );    # skip blanks
+
+      if ( $i =~ /^\$ORIGIN/i ) {   # $ORIGIN!
+        $end = ( split ( /\s+/, $i ) )[1];
+        $end .= ".$domain." if ( $end !~ /\.$/ );    # not FQDN
+
+        $last = lc $end;
+        print qq{(debug) "$i" specified.  Final = "$last".\n}
+          if ($debug);
+
+        next;
+      }
+
+      # parse the line
+      # HOST TTL CLASS TYPE VALUE
+      # TTL can be a number (seconds), or string
+      #  (1w1d1h1m1s), max of 63 chars. lib/dns/ttl.c,
+      #  function bind_ttl, BIND9.1.3.
+      # According to RFC1035, class and ttl can be
+      #  reversed. <grrr>
+      #
+      my ( $host, $type, $ip ) =
+        ( $i =~
+m!^(\S*)(?:\s+(?:\d+|(?:\d+[wdhms])+|IN|CS|CH|HS)){0,2}\s+(\w+)\s+(\S+)!i
+        );
+
+      $host = lc $host;    # lowercase the host
+      $type = uc $type;    # make sure the type (A,MX,etc) is uppercase
+
+      next unless ($type); # in SOA " 30 ; comment" ...
+
+      $host = $end if ( $host eq "@" );    # @ = ORIGIN
+
+      # what to do with host?  interact with last if necessary ...
+      if ( $host eq "" ) {    # it's a blank, use the last entry ...
+        $host = $last;
+      }
+      elsif ( $host !~ /\.$/ ) {    # relative hostname
+        $last = $host = "$host.$end";
+      }
+      else {                        # FQDN!
+        $last = $host;
+      }
+
+      # This needs to stay here for proper " A 10.0.0.0"
+      # behavior -- DON'T MOVE ME (again) BAD BAD THEO!
+      next unless ( $type eq "A" );    # skip non-A records
+
+      # should we skip?
+      if ( defined $toskip
+        && ( $host =~ /$toskip/o || $ip =~ /$toskip/o ) )
+      {
+        print "(debug) Skipping $host/$ip, matched toskip regexp ($toskip).\n"
+          if ($debug);
+        next;
+      }
+
+      # do network mapping
+      if ( keys %netmap ) {
+        my ($ipm) = &GenMask($ip);
+        foreach $i ( keys %netmap ) {
+          my ( $newnet, $netm, $mask ) = @{ $netmap{$i} };
+
+          unless ( ( $ipm ^ $netm ) & $mask ) {    # 0 if in match made
+            my ($ptr) = ( $ip =~ /\.(\d+)$/ );
+            print "(debug) $ip mapping to $newnet.$ptr ...\n"
+              if ($debug);
+            $ip = "$newnet.$ptr";
+            last;    # IPs should only match once ...
+          }
+        }
+      }
+
+      # figure out which network this IP is in ...
+      my ($network) = &IPinNetwork( $ip, $view, \%networks );
+      unless ( defined $network ) {
+        print "(debug) Not keeping $host = $ip, not in any network.\n"
+          if ($debug);
+        next;
+      }
+
+      # the original may or may not be all numeric (maps)
+      my ( $orig, $ptr ) = ( $ip =~ /^(.+)\.(\d+)$/ );
+      if ( exists( $mips{$view}->{$network}->{$orig}->{$ptr} ) )
+      {    # IP already has mapping!
+        print qq{The entry in "$map" for "$host" duplicated "},
+          $mips{$view}->{$network}->{$orig}->{$ptr},
+          qq{".\nKeeping the original entry.\n}
+          unless ($quiet);
+        print
+          "(debug) Not keeping $host = $ip, a PTR has already been defined ("
+          . $mips{$view}->{$network}->{$orig}->{$ptr} . ").\n"
+          if ($debug);
+        next;
+      }
+
+      print "(debug) Keeping $host = $ip, in network $network, view $view.\n"
+        if ($debug);
+
+      # Network/origin/ptr = host
+      $mips{$view}->{$network}->{$orig}->{$ptr} = $host;
+    }
+  }
+}
+
+# Check each output zone file to see if it needs changing
+HASH: {
+  while ( my ( $view, $nets ) = each %networks ) {
+    print "(debug) Checking view $view for file changes ...\n" if ($debug);
+
+    while ( my ( $net, $file ) = each %{$nets} ) {
+      my ( $orig, $ptr );
+      my ($map) = $maps{$view}->{$net};
+
+      %{ $mips{$view}->{$net} } = ()
+        unless ( defined $mips{$view}->{$net} );    # no IPs in net!
+           # Stole this from http://www.sysarch.com/perl/sort_paper.html ;)
+      foreach $orig (
+        sort {
+          pack( 'C*'   => split ( /\./, $a ) ) cmp
+            pack( 'C*' => split ( /\./, $b ) )
+
+        } keys %{ $mips{$view}->{$net} }
+        )
+      {
+        $map .= "\$ORIGIN "
+          . join ( ".", reverse( split ( /\./, $orig ) ) )
+          . ".in-addr.arpa.\n";    # append $ORIGIN to map
+        my $ptrs = $mips{$view}->{$net}->{$orig};
+        foreach $ptr ( sort { $a <=> $b } keys %{$ptrs} ) {
+
+          # Add PTR line to map
+          $map .= "$ptr\tPTR\t" . $ptrs->{$ptr} . "\n";
+        }
+
+      }
+
+      my ($hv) = Do_Hash($map);    # generate hash value for new map
+      print
+        "(debug) Generated hash values for $file (old/new): $hash{$file}/$hv.\n"
+        if ($debug);
+
+      if ( $hv ne $hash{$file} ) {    # maps are different!
+        print "(debug) File $file needs to be updated.\n" if ($debug);
+
+        my ($fserial);
+        my ($use) = $numordate{ $files{$file} }
+          || $numordate{"default"}
+          || "date";
+
+        print "(debug) File $file uses serial type $use.\n" if ($debug);
+
+        if ( $use eq "date" ) {
+          $fserial = &strftime( "%Y%m%d00", localtime(time) );
+
+          # if fserial > serial, then use fserial directly ...
+          if ( $fserial <= $serial{$file} )
+          {    # serial is >= fserial, add 1 to serial and use it if possible
+
+            if ( $serial{$file} =~ /99$/ ) {    # version 99! can't roll.
+              die
+qq#(fatal) Serial number $serial{$file} (file "$file") ends in 99 -- can't add 1!  Freaky!\n#;
+            }
+
+            $fserial = $serial{$file} + 1;
+          }
+        }
+        elsif ( $use eq "number" ) {
+          $fserial = $serial{$file} + 1;
+        }
+        else {
+          die qq{(fatal) Unknown serial type "$use".};
+        }
+
+        warn "(warn) Serial number for $file is at max.\n"
+          if ( $fserial > 4294967294 );
+
+        print "(debug) Changing serial number for $file from",
+          " $serial{$file} to $fserial\n"
+          if ($debug);
+
+        $map =~ s/(\s+SOA\s+\S+\s+\S+\s+(?:\(\s*)?)$serial{$file}/$1$fserial/s;
+
+        $file .= ".$ext" if ($ext);    # file or file.ext?
+
+        print qq{Updating file "$file"\n} unless ($quiet);
+        open( OUT, ">$file" )
+          || die "(fatal) Can't open $file for writing:$!";
+        print OUT $map;
+        close(OUT);
+      }
+      else {
+        print "File $file needs no modification.\n" unless ($quiet);
+      }
+    }
+  }
+}
+
+exit 0;
+
+# Is the given IP address in any of the specified networks?
+# note: this routine only checks on byte boundaries
+# Return undef if not, network number if yes.
+#
+{
+  my %cache = ();
+
+  sub IPinNetwork {
+    my ( $ip, $view, $networks ) = @_;  # IP to check, hash of networks to check
+
+    my ($orig) = ( $ip =~ /^(.+)\.\d+$/ );
+    return $cache{$view}->{$orig} if exists $cache{$view}->{$orig};
+
+    do {    # matches most specific network first (10.0.49 before 10 ...)
+      $ip =~ s/\.[^\.]+$//;    # remove last octet (host #)
+      if ( exists $networks->{$view}->{$ip} ) {
+        $cache{$view}->{$orig} = $ip;
+        return $ip;
+      }
+    } while ( $ip =~ /\./ );    # while there's a period in the IP
+
+    return undef;
+  }
+}
+
+# Generate a bitmask from an IP/Network/bit count.
+# Returns array of bitmasks from array of input values.
+#
+sub GenMask {
+  if ( $_[0] =~ /^\d+$/ ) {     # /27 ...
+    return ~( 2**( 32 - $_[0] ) - 1 );
+  }
+  else {                        # 255.255.255.224 ...
+    return unpack( "N", pack( 'C4' => split ( /\./, $_[0] ) ) );
+  }
+}
+
+# Parse the directive statements and plop the info in the right place.
+#
+sub Directives {
+  my ( $type, $vals ) = split ( /\s+/, $_[0], 2 );
+  print qq{(debug) mkrdns directive, type "$type", vals "$vals"\n}
+    if ($debug);
+
+  $type = lc $type;
+  if ( $type eq "map" ) {
+    my ( $nm, $nn ) = split ( /\s+/, $vals );
+    @{ $netmap{$nm} } = ( $nn, map { &GenMask($_) } split ( /\//, $nm ) );
+  }
+  elsif ( $type eq "skip" ) {
+    push ( @toskip, $vals );
+  }
+  elsif ( $type eq "skipzone" ) {
+    map {
+      my ( $v, $d ) = split ( /:/, $_, 2 );
+      ( $v, $d ) = ( "default", $v ) if ( !defined $d );
+      $zonetoskip{ lc $v }->{ lc $d } = 1;
+    } split ( /\s+/, $vals );
+  }
+  elsif ( $type eq "serialt" ) {
+
+    # $vals = "default|zone number|date"
+    $vals = lc $vals;
+    my ( $view, $zone, $nord ) = split ( /\s+/, $vals, 3 );
+    ( $view, $zone, $nord ) = ( 'default', $view, $zone )
+      if ( !defined $nord );    # backwards compatibility
+
+    die qq{(fatal) mkrdns directive "$type $vals" invalid.}
+      if ( $nord !~ /^(number|date)$/ );
+
+    $numordate{"$view:$zone"} = $nord;
+  }
+  elsif ( $type eq "ignoreslaves" ) {
+    $ignoreslaves = 1;
+  }
+  else {
+    die qq{(fatal) mkrdns directive type "$type" is unknown.};
+  }
+}
+
+# Generate actual lines from $GENERATE statements
+# This routine should actually handle all $GENERATE types, although we're
+# only going to use it for A records in mkrdns ...
+#
+sub Handle_GENERATE {
+  my ( $ORIGIN, $GENERATE ) = @_;
+  my (@toreturn) = ();
+
+  # $RANGE is 'start-stop[/step]', all must be positive
+  # $LHS/$RHS:
+  #	$ is replaced by iterator value.
+  #	\$ is a $ at the end.
+  #	$\{ is replaced by the iterator value and the actual { char.
+  #	Append $ORIGIN if $RHS!~/\.$/
+  #	${offset} where offset defaults to "0,1,d".
+  #		offset (integer),min width (0 padded),radix (doxX)
+  # $TYPE is A|AAAA|PTR|CNAME|NS
+
+  my ( $RANGE, $LHS, $TYPE, $RHS ) = ( split ( /\s+/, $GENERATE ) )[ 1 .. 4 ];
+  die qq{(fatal) Invalid \$GENERATE line: "$GENERATE"\n}
+    unless ( defined($RANGE)
+    && defined($LHS)
+    && defined($TYPE)
+    && defined($RHS) );
+
+  $TYPE = uc $TYPE;
+  die qq{(fatal) Invalid \$GENERATE line (bad type): "$GENERATE"\n}
+    unless ( $TYPE =~ /^(A|AAAA|PTR|CNAME|NS)$/ );
+
+  my ( $START, $STOP, $SKIP ) = ( $RANGE =~ m{^(\d+)-(\d+)(?:/(\d+))?$} );
+  if ( !defined($SKIP) || ( defined($SKIP) && $SKIP < 1 ) ) {
+    warn qq{(warn) Invalid \$GENERATE line (bad skip): "$GENERATE" (set to 1)\n}
+      if ( defined $SKIP );
+    $SKIP = 1;    # skip defaults to 1 if not specified.
+  }
+
+  die qq{(fatal) Invalid \$GENERATE line (non-pos value): "$GENERATE"\n}
+    unless ( $START > 0 && $STOP > 0 );
+
+  # Convert trouble-some combinations out of the way.
+  foreach ( $LHS, $RHS ) {
+    s/\$\\\{/\$\377/g;    # $\{ -> $\377
+
+    # Literal $'s in the statement
+    s/\\\$/\376/g;        # \$  -> \376
+    s/\$\$/\376/g;        # $$  -> \376
+
+    # Replace $ or ${...} w/ valid ${offset,width,radix} sections.
+    s@\$(?:{([^}]+)})?@
+			my($o,$w,$r) = split(/,/,(defined $1?$1:""));
+	
+			# Want to set to the default if not defined or invalid,
+			# only want to warn if invalid.
+			if ( !defined($o) || $o!~/^-?\d+$/ ) {
+				warn qq{(warn) Invalid \$GENERATE line (bad offset): "$GENERATE" (set to 0)\n}
+					if ( defined($o) );
+				
+				$o = 0;
+			}
+	
+			if ( !defined($w) || $w<1 ) {
+				warn qq{(warn) Invalid \$GENERATE line (bad width): "$GENERATE" (set to 1)\n}
+					if ( defined($w) );
+				
+				$w = 1;
+			}
+	
+			if ( !defined($r) || $r !~ /^[doxX]$/ ) {
+				warn qq{(warn) Invalid \$GENERATE line (bad radix): "$GENERATE" (set to d)\n}
+					if ( defined($r) );
+				
+				$r = "d";
+			}
+	
+			"\${$o,$w,$r}";
+		@ge;
+  }
+
+  for ( my ($IT) = $START ; $IT <= $STOP ; $IT += $SKIP ) {
+    $_ = "$LHS $RHS";
+
+    # The only $'s left in the string should be iterator values.
+    s@\${([^}]+)}@
+			my($o,$w,$r) = split(/,/,$1);
+			sprintf "%0$w$r", $IT+$o;
+		@ge;
+
+    tr/\377\376/{$/;    # Put the chars back in as literals.
+
+    my ( $l, $r ) = split;
+
+    if ( $ORIGIN ne "" ) {
+
+      # The right side of an A or AAAA record is an address...
+      foreach ( ( $TYPE =~ /^A/ ) ? $l : ( $l, $r ) ) {
+        $_ .= ".$ORIGIN" unless (/\.$/);
+      }
+    }
+
+    push ( @toreturn, "$l $TYPE $r" );
+  }
+
+  return @toreturn;
+}
+
+# This section of code takes in a line from the named configuration file and
+# puts the info in the appropriate spots.  This used to be in both the
+# named.conf and named.boot handlers in the main set of code, but the code
+# was exactly the same, so I put it here for maintainability.
+#
+sub Handle_Domain {
+  my ( $view, $type, $domain, $file, $files ) = @_;
+  $domain = lc $domain;
+
+  if ( $zonetoskip{$view}->{$domain} ) {
+    print "(debug) Skipping view $view, zone $domain, matched skipzone.\n"
+      if ($debug);
+    return;
+  }
+
+  unless ( $domain && $file ) {
+    warn
+qq{(warn) No file specified for view "$view", zone "$domain" in "$bootfile".\n};
+    return;
+  }
+
+  if ( $type =~ /^(slave|secondary)$/i && defined($ignoreslaves) ) {
+    print "(debug) Skipping slave $view:$domain\n" if ($debug);
+    return;
+  }
+
+  $file = "$nameddir/$file" if ( $file !~ m!^/! );
+  $file = &Handle_Path( $rootdir, $file );
+
+  if ( $domain =~ /\.arpa$/i ) {    # network
+                                    # The file is already being used!
+    die
+qq#(fatal) The zone file "$file" is being used by two zones!  Error in config file!\n($files->{$file} and $view:$domain ...)\n#
+      if ( exists $files->{$file} );
+
+    $files->{$file} = "$view:$domain";
+
+    if ( $type =~ /^(secondary|slave)$/i ) {
+      print "(debug) Skipping slave reverse zone $view:$domain\n"
+        if ($debug);
+      return;
+    }
+
+    $domain =~ s/\.in-addr\.arpa$//i;    # just the net ...
+    if ( $domain =~ /127$/ ) {           # silently skip 127.*
+      print "(debug) Skipping $file for the 127.* network.\n"
+        if ($debug);
+      return;
+    }
+    $domain = join ( ".", reverse( split ( /\./, $domain ) ) );
+    $networks{$view}->{$domain} = $file;
+    print
+      qq{(debug) Network "$domain", View "$view", File "$file", Type "$type".\n}
+      if ($debug);
+  }
+  else {    # "normal" domain, read in domains in order presented.
+    push ( @domains, "$view:$domain:$file" );
+    print
+      qq{(debug) Domain "$domain", View "$view", File "$file", Type "$type".\n}
+      if ($debug);
+  }
+}
+
+# Trim down a path to a standardized form.
+# ie: /path/../foo -> /foo
+#
+sub FixPath {
+  $_ = $_[0];
+
+  tr#/#/#s;                  # Remove multiple /'s
+  s#/\./#/#g;                # /./ -> /
+  s#/\.$##;                  # remove /.$
+  s#(^|/)[^/]*/\.\./#/#g;    # /[^/]/../ -> /
+  s#(^|/)[^/]*/\.\.$##g;     # remove /..$
+  s#^\./##;                  # remove ^./
+
+  return $_;
+}
+
+# Take a given path, handle a possibly different root directory, then return
+# it.
+#
+sub Handle_Path {
+  my ( $rootdir, $orig ) = @_;
+
+  my ($new) = &FixPath($orig);
+
+  if ( $new =~ m#^/?\.\.(/|$)# ) {
+    warn
+qq{(warn) Path "$_" tries to go beyond root directory ("$new").  Removing.\n}
+      unless ($quiet);
+    $new =~ s#^/?\.\.(/|$)##;
+  }
+
+  $new = &FixPath("$rootdir/$new");
+  if ( $orig ne $new ) {
+    print qq{(debug) Path changed from "$orig" to "$new".\n} if ($debug);
+    $orig = $new;
+  }
+
+  return $orig;
+}
+
+sub Do_Hash {
+  # Built-in (32bit checksum)
+  return unpack( "%32C*", $_[0] ) % 65535;   # generate 32-bit checksum for text
+}
+
+__END__
+
+=head1 NAME
+
+mkrdns - MaKe Reverse DNS (auto generate PTR maps)
+
+=head1 SYNOPSIS
+
+mkrdns [options] [configuration file]
+
+=head1 DESCRIPTION
+
+mkrdns is a program designed to auto-generate reverse DNS maps (IN PTR
+records).  Some programs already accompany the BIND source package
+that will do this kind of thing on a single domain or network basis.
+mkrdns will read either a named.boot or named.conf file, figure out
+which domains and networks to deal with, and then generate the reverse
+maps.
+
+You are deemed "in charge" of a network/domain if you are the primary
+DNS for a reverse zone, or if you are either the primary or secondary
+for a forward zone.  The exception to this rule is that the 127.*
+network is not auto-generated due to the "1 IN PTR localhost." issue.
+
+=head1 OPTIONS
+
+-debug           Print debugging information.  (this will
+                 print a B<LOT> of information, be warned.)
+
+-extension <ext> Append the given extension to the output
+                 files.  This is useful if you want to
+                 have the reverse maps generated, but want
+                 to check their contents before use.
+
+-help            The help screen.
+
+-quiet           Turn off warning messages (multiple A
+                 records -> IP, etc.)  Good for scripts,
+                 but you probably want to check on what
+                 the warnings report. 
+
+-rootdir <path>  Specify the path to the root directory
+                 that named will be running in.  This
+                 will handle anyone using a chrooted
+                 environment for named.  Everything except
+                 the configuration file is assumed to be
+                 under the new root.
+
+-version         Show mkrdns version information.
+
+=head1 CONFIGURATION FILE
+
+mkrdns reads the standard BIND configuration files I<named.boot> and
+I<named.conf>.  If you don't specify the full path to the file on the
+command line, mkrdns assumes that one (or both) will exist in /etc and
+will search for them.  If none are found, the program exits.  If one
+is found, it is used.  If both are found, named.conf is used.
+
+=head1 DIRECTIVES
+
+Think of directives as configuration options for mkrdns which are simply
+comments to BIND.  The current directives are B<map>, B<serialt>, B<skip>,
+and B<skipzone>.
+
+B<Map> allows you to map hosts to another network.  This was designed in
+for the purpose of handling DNS for a subnet of a class C network which
+you do not control.  (See the DNS & BIND O'Reilly and Associates book,
+3rd Ed., pg. 215-218) Assume that you have 10.4.4.32/27 (ie: you have
+the 32 IPs from 10.4.4.32 to 10.4.4.63 ...)  You want to do reverse
+mappings for those IPs, but you don't control 4.4.10.in-addr.arpa.
+How do you do it?  The solution is to become the master for another
+zone (such as 32.4.4.10.in-addr.arpa. or 32-63.4.4.10.in-addr.arpa.),
+and CNAME the correct reverse pointers to the ones you're in charge of.
+The format for the directive is:
+   map <network/mask> <new network>
+
+Ex: map 10.4.4.32/27 10.4.4.32-63
+
+This maps all hosts between 10.4.4.32 and 10.4.4.63 to 10.4.4.32-63.32
+to 10.4.4.32-63.63.
+
+B<Serialt> will change mkrdns's behavior with the serial number for
+certain zones.	By default, the serial number is assumed to be in I<date>
+format (YYYYMMDDVV, year/month/day/version).  However, you can tell mkrdns
+to treat the serial number as a regular number instead.  This allows
+for more than 100 zone changes a day, and has a bit more flexibility
+depending on the environment.  The format for the directive is:
+	serialt <view> <zone> <format>
+
+<view> specifies which view should be used for the behavior change.
+If not specified, mkrdns assumes "default".  <zone> is either "default"
+or the actual zone (ie: 0.0.0.10.in-addr.arpa).  <format> is either
+"date" or "number".
+
+Ex: serialt internal 1.168.192.in-addr.arpa number
+
+B<Skip> forces mkrdns to ignore certain hosts/IPs via regular
+expression. The concept is that there are some IN A records that
+you would like to skip and not create a reverse entry.  Skip allows
+this. (for instance, "foo IN A 10.4.4.32" and "mail IN A 10.4.4.32" both
+exist, but you want to force foo as the reverse lookup and ignore mail.
+The following example can do this for you.)  Format:
+   skip <regular expression>
+
+Ex: skip ^mail
+
+This will skip any host (or IP) that matches the "^mail" regular
+expression.  The host is the FQDN, and the IP is before mapping (see
+above).
+
+B<Skipzone> forces mkrdns to ignore certain zones while processing the
+named configuration file.  A possible use for this is where you have
+"bar.com" and "bar.net", and both of them should have the same host info
+(ie: foo.bar.com and foo.bar.net both have the same records.)  You want
+"bar.com" to be the reverse lookup for the IPs used.  So set the zone file
+setting to the same file (bar.zone), and then add "skipzone bar.net".
+B<NOTE:>  The skipzone argument must match EXACTLY with the zone name
+in the config file.  B<NOTE:> You can specify multiple zones in the same
+"skipzone" statement. (ie: "skipzone foo.com bar.com")  B<NOTE2:> If you are
+using views, the zone string must be in the format "view:zone".  If a view
+isn't given, "default" is assumed.
+
+B<ignoreslaves> tells mkrdns to ignore any forward slave domains in
+the configuration.  This is useful if, for instance, you are master for
+both a forward domain and reverse domain (say 168.192.in-addr.arpa)
+which go together, but you also have slave domains with hosts in the
+same reverse zone.
+
+
+The format of a directive differs (sorry) between named.conf and
+named.boot.  UNIX-style comments (the hash mark then the comment) are
+allowed.
+
+=head2 named.boot directives
+
+Directives look like a comment, so the format is simply:
+
+ ; mkrdns <directive type> <parameters>
+
+=head2 named.conf directives
+
+To make directives more efficient with BIND 8, the format is slightly
+different: 
+
+ /* mkrdns
+    <directive type> <parameters>
+    ...
+ */
+
+=head1 EXAMPLES
+
+B<mkrdns -e new /etc/named.boot>
+
+This will run mkrdns over the file /etc/named.boot.  Output files will
+be generated as <name>.new (i.e.: if the PTR zone file is called
+160.zone, the output will be 160.zone.new.)
+
+=head1 NOTES
+
+I tend to use this script like a lint check.  i.e.: Edit the proper
+zone files, then run mkrdns.
+
+As with most documentation, there are probably things that aren't mentioned
+in the docs that the script does/assumes/etc.  I apologize for any
+inaccuracies/omissions.  Let me know if there are any parts that have an
+"issue", and I'll see if I can't straighten it out.
+
+=head1 ASSUMPTIONS
+
+The <network>.zone reverse map files must already be created, be
+uniquely specified in the configuration file, and have the appropriate
+information (SOA/NS records, etc.) in there.  This script will strip
+out any PTR records, and then add them back in.  (This means anything
+like blank lines and comments will be moved to the top of the file.)
+$ORIGIN and $INCLUDE are striped as of mkrdns 1.3.
+
+You must be at least a secondary for all domains which reference IP
+networks for which you're responsible.  There is no means (currently
+at least) to specify a PTR record for a non-existent A record, so this
+script must have access to all A records that need to be "reversed".
+
+If you have more than 1 A record pointing to a specific IP, you can't
+have both be the PTR record.  This script takes the first A record it
+sees as the one used for the PTR record.  A warning is printed for any
+additional entries.  (While the RFCs don't prohibit multiple PTR records
+for the same IP, I have yet to find anyone who can give me a good reason
+to do it.)
+
+Map serial numbers default to be in YYYYMMDDVV format.  (YYYY = year,
+MM = month, DD = day, VV = version (00-99).  This script will convert
+your serial number to this format if it's not already.  I don't have too
+many daily DNS changes, so the action for not being able to update the
+serial number (ie: VV is at 99 and can't be increased) is to simply exit.
+If this is going to cause a problem for you, you can use the serialt
+directive to specify a zone (or the default) should treat the serial
+number as a number instead of using the date format.  Either way,
+a problem will come up when the serial number reaches 4294967295 (max
+value), but that's another story.  (mkrdns will print a warning if this
+is about to happen)
+
+=head1 AUTHOR
+
+Theo Van Dinter <felicity at mkrdns.org>
+
+=cut

Propchange: trunk/sbin/mkrdns
------------------------------------------------------------------------------
    svn:executable = *

Added: trunk/sbin/update-config
URL: http://svn.debian.org/wsvn/pf-tools/trunk/sbin/update-config?rev=442&op=file
==============================================================================
--- trunk/sbin/update-config (added)
+++ trunk/sbin/update-config Mon Mar  5 14:18:46 2007
@@ -1,0 +1,30 @@
+#!/usr/bin/perl -w
+##
+##  $Id$
+##
+##  Copyright (C) 2005 Olivier MOLTENI <olivier at molteni.net>
+##
+##  This program is free software; you can 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
+##  of the License, or (at your option) any later version.
+##
+##  This program 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.
+##
+##  You should have received a copy of the GNU General Public License
+##  along with this program; if not, write to the Free Software
+##  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+##
+
+#use strict;
+use warnings;
+
+# Librairies
+#------------------
+use PFTools::Update ;
+
+Do_update(@ARGV);
+

Propchange: trunk/sbin/update-config
------------------------------------------------------------------------------
    svn:executable = *

Added: trunk/sbin/update-links
URL: http://svn.debian.org/wsvn/pf-tools/trunk/sbin/update-links?rev=442&op=file
==============================================================================
--- trunk/sbin/update-links (added)
+++ trunk/sbin/update-links Mon Mar  5 14:18:46 2007
@@ -1,0 +1,8 @@
+#!/bin/sh
+
+BASEDIR='/master/Config'
+
+ln -sf $BASEDIR/lib/* /usr/local/lib/site_perl
+ln -sf $BASEDIR/bin/* /usr/local/bin
+ln -sf $BASEDIR/sbin/* /usr/local/sbin
+ln -snf $BASEDIR/config /etc/site_config

Propchange: trunk/sbin/update-links
------------------------------------------------------------------------------
    svn:executable = *




More information about the Pf-tools-commits mailing list