home *** CD-ROM | disk | FTP | other *** search
/ PC-Online 1996 May / PCOnline_05_1996.bin / linux / source / n / bind / bind-4.001 / bind-4~ / bind-4.9.3-BETA9 / contrib / decwrl / mkdb.pl < prev    next >
Perl Script  |  1993-09-07  |  6KB  |  261 lines

  1. #! /usr/bin/perl -w
  2. #
  3. # $Header: /usr/src/local/bind/4.9/mkdb.pl,v 1.37 1993/09/08 00:00:31 vixie Exp $
  4. #
  5. # from a hosts(5) database on standard input or argv,
  6. # build the .data and .zone files needed by named.boot
  7. #
  8. # $Log: mkdb.pl,v $
  9. % Revision 1.37  1993/09/08  00:00:31  vixie
  10. % ckp
  11. %
  12. #
  13.  
  14. #++ BEGIN user servicable parts 01/02
  15. $Domain = 'pa.dec.com';
  16. $Zone = 'decpa';
  17. %DelegOctet = (
  18.     "16", 2,        # net 16 delegates at the second octet in pa
  19.     );
  20. $Debug = 4;
  21. #-- END user servicable parts 01/02
  22.  
  23. $, = ' ';
  24. umask(022);
  25. chop($date = `/bin/date`);
  26. $Serial_File = 'version';
  27. $MX_File = 'mx_data';
  28. ($Domain_Pat = "$Domain") =~ s/(\W)/\\$1/go;
  29. $Domain_Pat = "\\.$Domain_Pat\$";
  30.  
  31. &Load_MX_Data();
  32. &Update_Serial_Number();
  33. &Update_Zone_Serials();    
  34. &Init_Zone_Datafiles();
  35. &Churn();
  36. &Close_Zone_Datafiles();
  37.  
  38. exit 0;
  39.  
  40. sub Find_Deleg {
  41.     local(@a) = @_;
  42.     local($x, $deleg);
  43.  
  44.     for ($x = 3;  $x >= 0;  $x--) {
  45.         $deleg = $DelegOctet{join('.', @a[0..$x])};
  46.         last if $deleg;
  47.     }
  48.     if ($x < 0) {
  49.         $deleg = 3;    # default for unspecified nets
  50.     }
  51.     @a = (    join('.', @a[0..($deleg-1)]),
  52.         join('.', reverse(@a[$deleg..3]))
  53.     );
  54.     print "Find_Deleg(@_) -> (@a)\n"        if $Debug & 0x01;
  55.     return @a;
  56. }
  57.  
  58. sub Write_RR {
  59.     local($fh, $name, $type, $data) = @_;
  60.  
  61.     print "Write_RR(@_)\n"                if $Debug & 0x02;
  62.     if ($name eq $Write_RR'last_name{$fh}) {
  63.         $name = '';
  64.     } else {
  65.         $Write_RR'last_name{$fh} = $name;
  66.     }
  67.     printf $fh "%-30s in %-5s %s\n", $name, $type, $data;
  68. }
  69.  
  70. sub Load_MX_Data {
  71.     open(f, "<$MX_File") || die "$MX_File: $!";
  72.     local($name) = ('');
  73.     while (<f>) {
  74.         chop;
  75.         s/\#.*$//;    # delete inline comments like this one
  76.         s/\s+$//;    # delete trailing whitespace
  77.         next unless length($_);
  78.         if (/^\s+/) {
  79.             $_ = $';    # default name
  80.         } elsif (/\s+/) {
  81.             $name = $`;    # specified name
  82.             $_ = $';
  83.         } else {
  84.             warn "$MX_File:$.: bad format ($_)\n";
  85.             next;
  86.         }
  87.         ($cost, $target, @rest) = split;
  88.         if ($cost <= 0 || $cost > 32767) {
  89.             warn "$MX_File:$.: bad MX cost ($cost)\n";
  90.             next;
  91.         }
  92.         if ($#rest >= $[) {
  93.             warn "$MX_File:$.: extra tokens ($_)\n";
  94.             next;
  95.         }
  96.         $MX_Data{$name} = '' unless defined($MX_Data{$name});
  97.         $MX_Data{$name} .= "$cost $target\n";
  98.     }
  99.     close(f);
  100. }
  101.  
  102. sub Write_MX_Data {
  103.     local($zone, $name) = @_;
  104.     local($n, $d, $_);
  105.  
  106.     print "Write_MX_Data(@_)\n"            if $Debug & 0x04;
  107.     foreach $n ($name, "*") {
  108.         foreach $d (split(/\n/, $MX_Data{$n})) {
  109.             &Write_RR($zone, $name, 'mx', $d);
  110.         }
  111.     }
  112. }
  113.  
  114. sub Update_Serial_Number {
  115.     local(*f);
  116.  
  117.     if (open(f, "<$Serial_File") && ($Serial_No = <f>)) {
  118.         close(f);
  119.     } else {
  120.         $Serial_No = 0;
  121.     }
  122.  
  123.     $Serial_No++;
  124.  
  125.     open(f, ">$Serial_File") || die "$Serial_File: $!";
  126.     print f "$Serial_No\n";
  127.     close(f);
  128.  
  129.     print "*** New serial number is $Serial_No\n";
  130. }
  131.  
  132. sub Update_Zone_Serials {
  133.     local(*f, $zonefile, $zone);
  134.  
  135.     foreach $zonefile (<*.zone>) {
  136.         $zone = $zonefile;
  137.         $zone =~ s/\.zone$//;
  138.         $Zones{$zone}++ unless ($zone eq $Zone);
  139.         print "*** updating zone file '$zonefile'\n";
  140.         open(f, "<$zonefile") || die "$zonefile: $!";
  141.         @f = <f>;
  142.         open(f, ">$zonefile.NEW") || die "$zonefile.NEW: $!";
  143.         foreach (@f) {
  144.             $_ = $`.$Serial_No.$1."\n" if (/\d+(\s+\;Serial)/);
  145.             print f;
  146.         }
  147.         close(f) || die "$zonefile.NEW: $!";
  148.     }
  149.  
  150.     print "*** Zone file serial numbers updated\n";
  151. }
  152.  
  153. sub Init_Zone_Datafiles {
  154.     #
  155.     # our name servers are considered authoritative for the following
  156.     # zones of in-addr.arpa.  we create a .data file for each here.  None
  157.     # of them have SOA's since we expect them to be $INCLUDE'd by .zone
  158.     # files.
  159.     #
  160.     local($zone);
  161.  
  162.     foreach $zone (sort(keys(%Zones))) {
  163.         print "*** Init'ing zone ".$zone."\n";
  164.         open($zone, ">$zone.data.NEW") || die "$zone.data.NEW: $!";
  165.         $rzone = join('.', reverse(split(/\./, $zone)))
  166.                . '.in-addr.arpa.';
  167.         print $zone "; $zone.data ($zone - $rzone) $date\n";
  168.         print $zone '$ORIGIN '.$rzone."\n";
  169.     }
  170.  
  171.     # the main host->addr file has no origin statement in it since
  172.     # its name is not mechanically translatable to its zone.
  173.     open($Zone, ">$Zone.data.NEW") || die "$Zone.data.NEW: $!";
  174.     &Write_MX_Data($Zone, "@");
  175. }
  176.  
  177. sub Close_Zone_Datafiles {
  178.     foreach ($Zone, keys(%Zones)) {
  179.         close($_) || die "$_.data.NEW: $!";
  180.         rename("$_.data", "$_.data.BAK");
  181.         rename("$_.data.NEW", "$_.data") || die "rename1 ($_): $!";
  182.         rename("$_.zone", "$_.zone.BAK");
  183.         rename("$_.zone.NEW", "$_.zone") || die "rename2 ($_): $!";
  184.     }
  185. }
  186.  
  187. sub Churn {
  188.     print "*** Churning\n";
  189. host:
  190.     while (<>) {
  191.     chop;
  192.  
  193.     # capture and convert comments
  194.     if (/^\s*\#/) {
  195.         $_ = ';' . $';
  196.         print $Zone "$_\n";
  197.         last host if (/BELOW HERE NOT REGISTERED WITH DOMAIN SERVER/);
  198.         next host;
  199.     }
  200.     s/\s*\#.*$//;
  201.  
  202.     # parse line, skip it if addr doesn't have four components
  203.     y/A-Z/a-z/;
  204.     ($a, $name, @aliases) = split;
  205.     next host if (4 != (@a = split(/\./, $a)));
  206.     $name =~ s/$Domain_Pat//o;
  207.  
  208.     #
  209.     # names that still have dots need to be qualified since they
  210.     # aren't local.
  211.     #
  212.     # only local names get MX RR's generated for them.
  213.     #
  214.     if ($name =~ /\./) {
  215.         $fullname = $name . '.';
  216.     } else {
  217.         &Write_RR($Zone, $name, 'a', $a);
  218.         #
  219.         # do not generate mx rr's for network or broadcast a rr's
  220.         # or for loopback addresses
  221.         #
  222.         if ($a[0] != 127 && $a[3] != 0 && $a[3] != 255) {
  223.             &Write_RR($Zone, $name, 'mx', "0 $name");
  224.             &Write_MX_Data($Zone, $name);
  225.         }
  226.         $fullname = $name . ".$Domain.";
  227.     }
  228.  
  229.     ($zone, $ptr) = &Find_Deleg(@a);
  230.  
  231.     #
  232.     # if this is a zone we support, write out a PTR for it
  233.     #
  234.     if ($Zones{$zone}) {
  235.         &Write_RR($zone, $ptr, 'ptr', $fullname);
  236.     }
  237.  
  238.     #
  239.     # iterate over the aliases, if any, and generate CNAMEs and PTRs.
  240.     #
  241.     foreach (@aliases) {
  242.         s/$Domain_Pat//o;
  243.  
  244.         # aliases that are the same as the basename aren't useful
  245.         next if ($_ eq $name);
  246.  
  247.         # CNAME makes sense only for local names
  248.         if (! /\./) {
  249.             $maybedot = '.' if ($name =~ /\./);
  250.             &Write_RR($Zone, $_, 'cname', $name.$maybedot);
  251.         }
  252.  
  253.         # PTR makes sense only for zones we support (NOTE: $_ smashed)
  254.         if ($Zones{$zone}) {
  255.             $_ .= ".$Domain" unless /\./;
  256.             &Write_RR($zone, $ptr, 'ptr', "$_.");
  257.         }
  258.     }
  259.     }
  260. }
  261.