home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / NETWORK / ISP / bind.4.8.3.lzh / BIND483 / EXAMPLES / h2n < prev    next >
Text File  |  1994-01-09  |  17KB  |  728 lines

  1. #!/usr/bin/perl
  2.  
  3. #NAME
  4. #
  5. #    h2n - Translate host table to name server file format
  6. #    $Date: 93/02/04 17:43:05 $  $Revision: 1.16 $
  7. #
  8. #SYNOPSIS
  9. #
  10. #    h2n -d DOMAIN -n NET [options]
  11.  
  12. # Various defaults
  13. $Host = `hostname`;
  14. chop($Host);
  15. $Host =~ s/\..*//;               
  16. $doaliases = 1;
  17. $domx = 1;
  18. $dowks = 0;
  19. $dotxt = 0;
  20. $dontdodomains = 0;
  21. $Bootfile = "./named.boot";
  22. $Hostfile = "/etc/hosts";
  23. $Commentfile = "";
  24. $Commentfileread = 0;
  25. $User = "root";
  26. $Pwd = `pwd`;
  27. $RespHost = "";
  28. $RespUser = "";
  29. $DefSerial = 1;
  30. $DefRefresh = 10800;
  31. $DefRetry = 3600;
  32. $DefExpire = 604800;
  33. $DefTtl = 86400;
  34. $DefMxWeight = 10;
  35. $Defsubnetmask = "";
  36. $ForceSerial = -1;
  37.  
  38. push(@bootmsgs, "primary\t0.0.127.IN-ADDR.ARPA db.127.0.0\n");
  39.  
  40. &PARSEARGS(@ARGV);
  41. &FIXUP;
  42.  
  43. open(HOSTS, $Hostfile) || die "can not open $Hostfile";
  44.  
  45. LINE: while(<HOSTS>){
  46.     next if /^#/;        # skip comment lines
  47.     next if /^$/;       # skip empty lines
  48.     chop;                # remove the trailing newline
  49.     tr/A-Z/a-z/;     # translate to lower case 
  50.  
  51.     ($data,$comment) = split('#', $_, 2);
  52.     ($addr, $names) = split(' ', $data, 2);
  53.     if ($names =~ /^[ \t]*$/) {
  54.     print STDERR "Bad line in hosts file ignored '$_'\n";
  55.     next LINE;
  56.     }
  57.  
  58.     # Match -e args
  59.     foreach $netpat (@elimpats){
  60.     next LINE if (/[.\s]$netpat/);
  61.     }
  62.  
  63.     # Process -c args
  64.     foreach $netpat (@cpats){
  65.     if (/\.$netpat/) {
  66.         ($canonical, $aliases) = split(' ', $names, 2);
  67.         $canonical =~ s/\.$netpat//; 
  68.         if($Cnames{$canonical} != 1){
  69.             printf DOMAIN "%-20s IN  CNAME %s.%s.\n", 
  70.                $canonical, $canonical, $cpatrel{$netpat};
  71.         $Cnames{$canonical} = 1;
  72.         }
  73.         next LINE;
  74.     }
  75.     }
  76.  
  77.     # Check that the address is in the address list.
  78.     $match = 'none';
  79.     foreach $netpat (@Netpatterns){
  80.     $match = $netpat, last if ($addr =~ /^$netpat\./);
  81.     }
  82.     next if ($match eq 'none');
  83.  
  84.     ($canonical, $aliases) = split(' ', $names, 2);  # separate out aliases
  85.     next if ($dontdodomains && $canonical =~ /\./);  # skip domain names
  86.     $canonical =~ s/$Domainpattern//;     # strip off domain if there is one
  87.     $Hosts{$canonical} .= $addr . " ";    # index addresses by canonical name
  88.     $Aliases{$addr} .= $aliases . " ";    # index aliases by address
  89.     $Comments{"$canonical-$addr"} = $comment;
  90.  
  91.     # Print PTR records
  92.     $file = $Netfiles{$match};
  93.     printf $file "%-30s\tIN  PTR   %s.%s.\n", 
  94.        &REVERSE($addr), $canonical, $Domain;
  95. }
  96.  
  97. #
  98. # Go through the list of canonical names.
  99. # If there is more than 1 address associated with the
  100. # name, it is a multi-homed host.  For each address 
  101. # look up the aliases since the aliases are associated 
  102. # with the address, not the canonical name.
  103. #
  104. foreach $canonical (keys %Hosts){
  105.     @addrs = split(' ', $Hosts{$canonical});
  106.     $numaddrs = $#addrs + 1;
  107.     foreach $addr (@addrs) {
  108.     #
  109.     # Print address record for canonical name.
  110.     #
  111.     if($Cnames{$canonical} != 1){
  112.         printf DOMAIN "%-20s IN  A     %s\n", $canonical, $addr;
  113.     } else {
  114.         print STDERR "$canonical - can't create A record because CNAME exists for name.\n";
  115.     }
  116.     #
  117.     # Print cname or address records for each alias.
  118.     # If this is a multi-homed host, print an address
  119.     # record for each alias.  If this is a single address
  120.     # host, print a cname record.
  121.     #
  122.     if ($doaliases) {
  123.         @aliases = split(' ', $Aliases{$addr});
  124.         foreach $alias (@aliases){
  125.         #
  126.         # Skip over the alias if the alias and canonical
  127.         # name only differ in that one of them has the
  128.         # domain appended to it.
  129.         #
  130.             next if ($dontdodomains && $alias =~ /\./); # skip domain names
  131.         $alias =~ s/$Domainpattern//;
  132.         if($alias eq $canonical){
  133.             next;
  134.         }
  135.  
  136.         if($numaddrs > 1){
  137.             printf DOMAIN "%-20s IN  A     %s\n", $alias, $addr;
  138.         } else {
  139.             #
  140.             # Flag aliases that have already been used
  141.             # in CNAME records or have A records.
  142.             #
  143.             if(($Cnames{$alias} != 1) && (!$Hosts{$alias})){
  144.             printf DOMAIN "%-20s IN  CNAME %s.%s.\n", 
  145.                    $alias, $canonical, $Domain;
  146.             $Cnames{$alias} = 1;
  147.             } else {
  148.             print STDERR "$alias - CNAME or A exists already; alias ignored\n";
  149.             }
  150.         }
  151.         }
  152.     }
  153.     }
  154.     if ($domx) {
  155.     &MX($canonical, @addrs);
  156.     }
  157.     if ($dotxt) {
  158.     &TXT($canonical, @addrs);
  159.     }
  160.     if ($Commentfile ne "") {
  161.     &DO_COMMENTS($canonical, @addrs);
  162.     }
  163. }
  164.  
  165. # Deal with spcl's
  166. if (-r "spcl.$Domainfile") {
  167.     print DOMAIN "\$INCLUDE spcl.$Domainfile\n";
  168. }
  169. foreach $n (@Networks) {
  170.     if (-r "spcl.$n") {
  171.     $file = "DB.$n";
  172.     print $file "\$INCLUDE spcl.$n\n";
  173.     }
  174. }
  175.  
  176. # generate boot.* files
  177. &GEN_BOOT;
  178.  
  179. exit;
  180.  
  181.  
  182. #
  183. # Generate resource record data for
  184. # strings from the commment field that
  185. # are found in the comment file (-C).
  186. #
  187. sub DO_COMMENTS {
  188.     local($canonical, @addrs) = @_;
  189.     local(*F, @c, $c, $a, $comments);
  190.     
  191.     if (!$Commentfileread) {
  192.     open(F, $Commentfile) || die "Unable to open file $Commentfile: $!";
  193.     $Commentfileread++;
  194.     while (<F>) {
  195.         chop;
  196.         ($key, $c) = split(':', $_, 2);
  197.         $CommentRRs{$key} = $c;
  198.     }
  199.     close(F);
  200.     }
  201.     
  202.     foreach $a (@addrs) {
  203.     $key = "$canonical-$a";
  204.     $comments .= " $Comments{$key}";
  205.     }
  206.  
  207.     @c = split(' ', $comments);
  208.     foreach $c (@c) {
  209.     if($CommentRRs{$c}){
  210.         printf DOMAIN "%-20s %s\n", $canonical, $CommentRRs{$c};
  211.     }
  212.     }
  213. }
  214.  
  215.  
  216. #
  217. # Generate MX record data
  218. #
  219. sub MX {
  220.     local($canonical, @addrs) = @_;
  221.     local($first, $a, $key, $comments);
  222.  
  223.     if($Cnames{$canonical}){
  224.     print STDERR "$canonical - can't create MX record because CNAME exists for name.\n";
  225.     return;
  226.     }
  227.     $first = 1;
  228.  
  229.     foreach $a (@addrs) {
  230.     $key = "$canonical-$a";
  231.     $comments .= " $Comments{$key}";
  232.     }
  233.     
  234.     if ($comments !~ /\[no smtp\]/) {
  235.         # Add WKS if requested
  236.         if ($dowks) {
  237.         foreach $a (@addrs) {
  238.             printf DOMAIN "%-20s IN  WKS   %s TCP SMTP\n", $canonical, $a;
  239.         }
  240.         }
  241.     printf DOMAIN "%-20s IN  MX    %s %s.%s.\n", $canonical, $DefMxWeight, 
  242.            $canonical, $Domain; 
  243.     $first = 0;
  244.     }
  245.     if ($#Mx >= 0) {
  246.     foreach $a (@Mx) {
  247.         if ($first) {
  248.         printf DOMAIN "%-20s IN  MX    %s\n", $canonical, $a; 
  249.         $first = 0;
  250.         } else {
  251.         printf DOMAIN "%-20s IN  MX    %s\n", "", $a; 
  252.         }
  253.     }
  254.     }
  255.  
  256. }
  257.  
  258.  
  259. #
  260. # Generate TXT record data
  261. #
  262. sub TXT {
  263.     local($canonical, @addrs) = @_;
  264.     local($a, $key, $comments);
  265.  
  266.     foreach $a (@addrs) {
  267.     $key = "$canonical-$a";
  268.     $comments .= " $Comments{$key}";
  269.     }
  270.     $comments =~ s/\[no smtp\]//g;
  271.     $comments =~ s/^\s*//;
  272.     $comments =~ s/\s*$//;
  273.     
  274.     if ($comments ne "") {
  275.     printf DOMAIN "%s IN  TXT   \"%s\"\n", $canonical, $comments;
  276.     }
  277. }
  278.  
  279.  
  280. #
  281. # Create the SOA record at the beginning of the file
  282. #
  283. sub MAKE_SOA {
  284.     local($fname, $file) = @_;
  285.     local($s);
  286.  
  287.     if ( -s $fname) {
  288.     open($file, "$fname") || die "Unable to open $fname: $!";
  289.     $_ = <$file>;
  290.     chop;
  291.     if (/\($/) {
  292.         if (! $soa_warned) {
  293.         print STDERR "Converting SOA format to new style.\n";
  294.         $soa_warned++;
  295.         }
  296.         if ($ForceSerial > 0) {
  297.         $Serial = $ForceSerial;
  298.         } else {
  299.         ($Serial, $junk) = split(' ', <$file>, 2);
  300.         $Serial++;
  301.         }
  302.         if (!defined($Refresh)) {
  303.         ($Refresh, $junk) = split(' ', <$file>, 2);
  304.         ($Retry, $junk) = split(' ', <$file>, 2);
  305.         ($Expire, $junk) = split(' ', <$file>, 2);
  306.         ($Ttl, $junk) = split(' ', <$file>, 2);
  307.         }
  308.     } else {
  309.         split(' ');
  310.         if ($#_ == 11) {
  311.         if ($ForceSerial > 0) {
  312.             $Serial = $ForceSerial;
  313.         } else {
  314.             $Serial = ++@_[6];
  315.         }
  316.         if (!defined($Refresh)) {
  317.             $Refresh = @_[7];
  318.             $Retry = @_[8];
  319.             $Expire = @_[9];
  320.             $Ttl = @_[10];
  321.         }
  322.         } else {
  323.         print STDERR "Improper format SOA in $fname.\n";
  324.         print STDERR "I give up ... sorry.\n";
  325.         exit(1);
  326.         }
  327.     }
  328.     close($file);
  329.     } else {
  330.     if ($ForceSerial > 0) {
  331.         $Serial = $ForceSerial;
  332.     } else {
  333.         $Serial = $DefSerial;
  334.     }
  335.     if (!defined($Refresh)) {
  336.         $Refresh = $DefRefresh;
  337.         $Retry = $DefRetry;
  338.         $Expire = $DefExpire;
  339.         $Ttl = $DefTtl;
  340.     }
  341.     close($file);
  342.     }
  343.  
  344.     open($file, "> $fname") || die "Unable to open $fname: $!";
  345.  
  346.     print $file "\@ IN  SOA $RespHost $RespUser ";
  347.     print $file "( $Serial $Refresh $Retry $Expire $Ttl )\n";
  348.     foreach $s (@Servers) {
  349.     print $file "  IN  NS  $s\n";
  350.     }
  351.     print $file "\n";
  352. }
  353.  
  354.  
  355. #
  356. # Reverse the octets of an IP address and append
  357. # in-addr.arpa.
  358. #
  359. sub REVERSE {
  360.     join('.', reverse(split('\.', $_[0]))) . '.IN-ADDR.ARPA.';
  361. }
  362.  
  363.  
  364. #
  365. # Establish what we will be using for SOA records
  366. #
  367. sub FIXUP {
  368.     local($s);
  369.  
  370.     if ($Host =~ /\./) {
  371.     $RespHost = "$Host.";
  372.     } else {
  373.     $RespHost = "$Host.$Domain.";
  374.     }
  375.     $RespHost =~ s/\.\././g;
  376.  
  377.     if ($User =~ /@/) {                # -u user@...
  378.     if ($User =~ /\./) {
  379.         $RespUser = "$User.";        # -u user@terminator.movie.edu
  380.     } else {
  381.         $RespUser = "$User.$Domain.";     # -u user@terminator
  382.     }
  383.     $RespUser =~ s/@/./;
  384.     } elsif ($User =~ /\./) {
  385.     $RespUser = "$User.";            # -u user.terminator.movie.edu
  386.     } else {
  387.     $RespUser = "$User.$RespHost";        # -u user
  388.     }
  389.     $RespUser =~ s/\.\././g;            # Strip any ".."'s to "."
  390.  
  391.     # Clean up nameservers
  392.     if (!defined(@Servers)) {
  393.     push(@Servers, "$Host.$Domain.");
  394.     } else {
  395.     foreach $s (@Servers) {
  396.         if ($s !~ /\./) {
  397.         $s .= ".$Domain";
  398.         }
  399.         if ($s !~ /\.$/) {
  400.         $s .= ".";
  401.         }
  402.     }
  403.     }
  404.  
  405.     # Clean up MX hosts
  406.     foreach $s (@Mx) {
  407.     $s =~ s/:/ /;
  408.     if ($s !~ /\./) {
  409.         $s .= ".$Domain";
  410.     }
  411.     if ($s !~ /\.$/) {
  412.         $s .= ".";
  413.     }
  414.     }
  415.  
  416.     # Now open boot file and print saved data
  417.     open(BOOT, "> $Bootfile")  || die "can not open $Bootfile";
  418.     print BOOT "\ndirectory $Pwd\n";
  419.     foreach $line (@bootmsgs) {
  420.     print BOOT $line;
  421.     }
  422.     print BOOT "cache\t. db.cache\n";
  423.  
  424.     # Go ahead and start creating files and making SOA's
  425.     foreach $i (@makesoa) {
  426.     ($x1, $x2) = split(' ', $i);
  427.     &MAKE_SOA($x1, $x2);
  428.     }
  429.     printf DOMAIN "%-20s IN  A     127.0.0.1\n", "localhost";
  430.     
  431.     $file = "DB.127.0.0.1";
  432.     &MAKE_SOA("db.127.0.0", $file);
  433.     printf $file "%-30s\tIN  PTR   localhost.\n", &REVERSE("127.0.0.1");
  434.     close($file);
  435. }
  436.  
  437.  
  438. sub PARSEARGS {
  439.     local(@args) = @_;
  440.     local($i, $net, $subnetmask, $option, $tmp1);
  441.     local(*F, $file, @newargs, @targs);
  442.  
  443.     $i = 0;
  444.     while ($i <= $#args){
  445.     $option = $args[$i];
  446.     if($option eq "-d"){
  447.         $Domain = $args[++$i];
  448.         $Domainpattern = "." . $Domain;
  449.         $Domainpattern =~ s/\./\\./g;        # for stripping off domain
  450.  
  451.         # Add entry to the boot file.
  452.         $Domainfile = $Domain;
  453.         $Domainfile =~ s/\..*//;
  454.         push(@makesoa, "db.$Domainfile DOMAIN");
  455.         push(@bootmsgs, "primary\t$Domain db.$Domainfile\n");
  456.  
  457.     } elsif ($option eq "-f"){
  458.         $file = $args[++$i];
  459.         open(F, $file) || die "Unable to open args file $file: $!";
  460.         while (<F>) {
  461.         next if (/^#/);
  462.         next if (/^$/);
  463.         chop;
  464.         @targs = split(' ');
  465.         push(@newargs, @targs);
  466.         }
  467.         close(F);
  468.         &PARSEARGS(@newargs);
  469.  
  470.     } elsif ($option eq "-z"){
  471.         $Bootsecsaveaddr = $args[++$i];
  472.         if (!defined($Bootsecaddr)) {
  473.         $Bootsecaddr = $Bootsecsaveaddr;
  474.         }
  475.  
  476.     } elsif ($option eq "-Z"){
  477.         $Bootsecaddr = $args[++$i];
  478.         if (!defined($Bootsecsaveaddr)) {
  479.         $Bootsecsaveaddr = $Bootsecaddr;
  480.         }
  481.  
  482.     } elsif ($option eq "-b"){
  483.         $Bootfile = $args[++$i];
  484.  
  485.     } elsif ($option eq "-A"){
  486.         $doaliases = 0;
  487.  
  488.     } elsif ($option eq "-M"){
  489.         $domx = 0;
  490.  
  491.     } elsif ($option eq "-w"){
  492.         $dowks = 1;
  493.  
  494.     } elsif ($option eq "-D"){
  495.         $dontdodomains = 1;
  496.  
  497.     } elsif ($option eq "-t"){
  498.         $dotxt = 1;
  499.  
  500.     } elsif ($option eq "-u"){
  501.         $User = $args[++$i];
  502.  
  503.     } elsif ($option eq "-s"){
  504.         while ($args[++$i] !~ /^-/ && $i <= $#args) {
  505.         push(@Servers, $args[$i]);
  506.         }
  507.         $i--;
  508.  
  509.     } elsif ($option eq "-m"){
  510.         if ($args[++$i] !~ /:/) {
  511.         print STDERR "Improper format for -m option ignored ($args[$i]).\n";
  512.         }
  513.         push(@Mx, $args[$i]);
  514.  
  515.     } elsif ($option eq "-c"){
  516.         $tmp1 = $args[++$i];
  517.         if ($tmp1 !~ /\./) {
  518.         $tmp1 .= ".$Domain";
  519.         }
  520.         $tmp2 = $tmp1;
  521.         $tmp2 =~ s/\./\\./g; 
  522.         $cpatrel{$tmp2} = $tmp1;
  523.         push(@cpats, $tmp2);
  524.  
  525.     } elsif ($option eq "-e"){
  526.         $tmp1 = $args[++$i];
  527.         if ($tmp1 !~ /\./) {
  528.         $tmp1 .= ".$Domain";
  529.         }
  530.         $tmp1 =~ s/\./\\./g; 
  531.         push(@elimpats, $tmp1);
  532.  
  533.     } elsif ($option eq "-h"){
  534.         $Host = $args[++$i];
  535.  
  536.     } elsif ($option eq "-o"){
  537.         if (   $args[++$i] !~ /^[:\d]*$/ 
  538.         || split(':', $args[$i]) != 4) {
  539.         print STDERR "Improper format for -o ($args[$i]).\n";
  540.         print STDERR "I give up ... sorry.\n";
  541.         exit(1);
  542.         }
  543.         ($DefRefresh, $DefRetry, $DefExpire, $DefTtl) = split(':', $args[$i]);
  544.  
  545.     } elsif ($option eq "-i"){
  546.         $ForceSerial = $args[++$i];
  547.  
  548.     } elsif ($option eq "-H"){
  549.         $Hostfile = $args[++$i];
  550.         if (! -r $Hostfile || -z $Hostfile) {
  551.         print STDERR "Invalid file specified for -H ($Hostfile).\n";
  552.         print STDERR "I give up ... sorry.\n";
  553.         exit(1);
  554.         }
  555.  
  556.     } elsif ($option eq "-C"){
  557.         $Commentfile = $args[++$i];
  558.         if (! -r $Commentfile || -z $Commentfile) {
  559.         print STDERR "Invalid file specified for -C ($Commentfile).\n";
  560.         print STDERR "I give up ... sorry.\n";
  561.         exit(1);
  562.         }
  563.  
  564.     } elsif ($option eq "-N"){
  565.         $Defsubnetmask = $args[++$i];
  566.         if (   $Defsubnetmask !~ /^[.\d]*$/ 
  567.         || split('\.', $Defsubnetmask) != 4) {
  568.         print STDERR "Improper subnet mask ($Defsubnetmask).\n";
  569.         print STDERR "I give up ... sorry.\n";
  570.         exit(1);
  571.         }
  572.         if ($#Networks >= 0) {
  573.         print STDERR "Hmm, -N option should probably be specified before any -n options.\n";
  574.         }
  575.  
  576.     } elsif ($option eq "-n"){
  577.         ($net, $subnetmask) = split(':',$args[++$i]);
  578.         if ($subnetmask eq "") {
  579.         foreach $tmp1 (&SUBNETS($net, $Defsubnetmask)) {
  580.             &BUILDNET($tmp1);
  581.         }
  582.         } else {
  583.         if (   $subnetmask !~ /^[.\d]*$/ 
  584.             || split('\.', $subnetmask) != 4) {
  585.             print STDERR "Improper subnet mask ($subnetmask).\n";
  586.             print STDERR "I give up ... sorry.\n";
  587.             exit(1);
  588.         }
  589.         foreach $tmp1 (&SUBNETS($net, $subnetmask)) {
  590.             &BUILDNET($tmp1);
  591.         }
  592.         }
  593.  
  594.     } elsif ($option eq "-1"){
  595.         print STDERR "Option -1 is obsolete ... ignored.\n";
  596.  
  597.     } elsif ($option eq "-F"){
  598.         print STDERR "Option -F is now the default (and only) way ... ignored.\n";
  599.  
  600.     } else {
  601.         if($option =~ /^-.*/){
  602.         print STDERR "Unknown option: $option ... ignored.\n";
  603.         }
  604.     }
  605.     $i++;
  606.     }
  607.     
  608.     if (!defined(@Networks) || $Domain eq "") {
  609.     print STDERR "Must specify at least -d and one -n.\n";
  610.     print STDERR "I give up ... sorry.\n";
  611.     exit(1);
  612.     }
  613. }
  614.  
  615.  
  616. sub BUILDNET {
  617.     local($net) = @_;
  618.  
  619.     push(@Networks, $net);
  620.     #
  621.     # Create pattern to match against.  
  622.     # The dots must be changed to \. so they 
  623.     # aren't used as wildcards.
  624.     #
  625.     $netpat = $net;
  626.     $netpat =~ s/\./\\./g;
  627.     push(@Netpatterns, $netpat);
  628.  
  629.     #
  630.     # Create db files for PTR records.
  631.     # Save the file names in an array for future use.
  632.     #
  633.     $netfile = "DB.$net";
  634.     $Netfiles{$netpat} = $netfile;
  635.     push(@makesoa, "db.$net $netfile");
  636.  
  637.     # Add entry to the boot file.
  638.     $revaddr = &REVERSE($net);
  639.     chop($revaddr);   # remove trailing dot
  640.     push(@bootmsgs, "primary $revaddr db.$net\n");
  641. }
  642.  
  643.  
  644. #
  645. # Calculate all the subnets from a network number and mask.
  646. # This was originally written for awk, not perl.
  647. #
  648. sub SUBNETS {
  649.     local($network, $mask) = @_;
  650.     local(@ans, @net, @mask, $buf, $number, $i, $j, $howmany);
  651.  
  652.     @net = split(/\./, $network);
  653.     @mask = split(/\./, $mask);
  654.     $number = '';
  655.     #
  656.     # Only expand bytes 1, 2, or 3
  657.     # for DNS purposes
  658.     #
  659.     for ($i = 0; $i < 3; $i++) {
  660.     if ($mask[$i] == 255) {
  661.         $number = $number . $net[$i] . '.';
  662.     } elsif (($mask[$i] == 0) || $mask[$i] eq '') {
  663.         push(@ans, $network);
  664.         last;
  665.     } else {
  666.         #
  667.         # This should be done as a bit-wise or
  668.         # but awk does not have an or symbol
  669.         #
  670.         $howmany = 255 - $mask[$i];
  671.         for ($j = 0; $j <= $howmany; $j++) {
  672.         if ($net[$i] + $j <= 255) {
  673.             $buf = sprintf("%s%d", $number, $net[$i] + $j);
  674.             push(@ans, $buf);
  675.         }
  676.         }
  677.         last;
  678.     }
  679.     }
  680.  
  681.     if ($#ans == -1) {
  682.     push(@ans, $network);
  683.     }
  684.     
  685.     @ans;
  686. }
  687.  
  688.  
  689. sub GEN_BOOT {
  690.     local(*F, $revaddr, $n);
  691.  
  692.     if (! -e "boot.cacheonly") {
  693.     open(F, ">boot.cacheonly") || die "Unable to open boot.cacheonly: $!";
  694.     print F "directory\t$Pwd\n";
  695.     print F "primary\t\t0.0.127.IN-ADDR.ARPA    db.127.0.0\n";
  696.     print F "cache\t\t.                       db.cache\n";
  697.     close(F);
  698.     }
  699.     
  700.     if (defined($Bootsecaddr)) {
  701.     open(F, ">boot.sec") || die "Unable to open boot.sec: $!";
  702.     print  F "directory\t$Pwd\n";
  703.     print  F "primary\t\t0.0.127.IN-ADDR.ARPA    db.127.0.0\n";
  704.     printf F "secondary\t%-23s $Bootsecaddr\n", $Domain;
  705.     foreach $n (@Networks) {
  706.         $revaddr = &REVERSE($n);
  707.         chop($revaddr);
  708.         printf F "secondary\t%-23s $Bootsecaddr\n", $revaddr;
  709.     }
  710.     print  F "cache\t\t.                       db.cache\n";
  711.     close(F);
  712.  
  713.     open(F, ">boot.sec.save") || die "Unable to open boot.sec.save: $!";
  714.     print  F "directory\t$Pwd\n";
  715.     print  F "primary\t\t0.0.127.IN-ADDR.ARPA    db.127.0.0\n";
  716.     printf F "secondary\t%-23s $Bootsecsaveaddr db.%s\n", 
  717.            $Domain, $Domainfile;
  718.     foreach $n (@Networks) {
  719.         $revaddr = &REVERSE($n);
  720.         chop($revaddr);
  721.         printf F "secondary\t%-23s $Bootsecsaveaddr db.%s\n", 
  722.            $revaddr, $n;
  723.     }
  724.     print  F "cache\t\t.                       db.cache\n";
  725.     close(F);
  726.     }
  727. }
  728.