⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 makezones

📁 早期freebsd实现
💻
📖 第 1 页 / 共 3 页
字号:
    { last if ($net == $rzone_number[$rzone]); }      if ($rzone >= $rzone_count)    {     $net = ($d >= 192)? "$d.$c.$b" : "$d.$c";     do error("$net is not a known network.");     }  else    {    $thisaddress = "$d.$c.$b.$a";     if ($addresses{"$thisaddress"} != "")      {      do error("duplicate IP address $thisaddress specified for a PTR record.\n".        "** The first occurrence was in line $addresses{$thisaddress}.");      }    else      {       local($handle) = "REVERSE$rzone";      print $handle "$a";      print $handle ".$b" if $d < 192;       print $handle "  $ttl $class  PTR  $rest";      $addresses{"$thisaddress"} = $nline;      }      }             return;   }# Type HINFO - host information; no further checkingif ($type eq "HINFO")  {  print FORWARD "$printname  $ttl  $class  HINFO  $rest";  return;     }# Type MX - mail exchanger; there must be a preference and# a fully-qualified gateway name.if ($type eq "MX")  {  ($pref,$gateway) = split(/\s+/, $rest, 2);  do check_fqn($gateway, "MX");  if ($pref !~ /^\d+$/)    {    do error("invalid MX preference field (not all digits).");     }  print FORWARD "$printname  $ttl  $class  MX  $pref  $gateway";  return;   }# Type TXT - arbitrary descriptive text, enclosed in double quotesif ($type eq "TXT")  {  if ($rest !~ /^\".*\"\s*$/)    {    do error("malformed TXT record - must use double quotes.");    }  print FORWARD "$printname  $ttl  $class  TXT  $rest";  return;   }# Type WKS - well-known services. This commonly is continued onto# other lines, so we must handle continuations. Check the protocol# field is either TCP or UDP, then check all the services appear# in the $services file, if it is set (typically /etc/services).# Check the address is in a known network, unless external.if ($type eq "WKS")  {  ($address,$proto,$rest) = split(/\s+/, $rest, 3);    # Check the address     if (!$external_net)    {    local($a,$b,$c,$d) =       $address =~ /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;        if ($a eq "")      {       do error("IP address on WKS record is incomplete");      return;      }        if ($a > 255 || $b > 255 || $c > 255 || $d > 255)       {      do error("IP address contains component with value greater than 255.");      return;      }               $net = ($a << 24) + ($b << 16);    $net += ($c << 8) if $a >= 192;         for ($rzone = 0; $rzone < $rzone_count; $rzone++)      { last if ($net == $rzone_number[$rzone]); }          if ($rzone >= $rzone_count)      {       $net = ($a >= 192)? "$a.$b.$c" : "$a.$b";       do error("$net is not a known network.");       }    }        # Check the protocol    if ($proto ne "UDP" && $proto ne "TCP")    {    do error("protocol in WKS record must be \"UCP\" or \"TCP\".");    }      # Start of line prefix - the rest of the line is in $rest     $pref = "$printname  $ttl  $class  WKS  $address $proto";   # Allow continuation bracket at start of list only     if (substr($rest, 0, 1) eq "(")     {     $continued = 1;    ($list) = $rest =~ /^\(\s*(.+)$/;    }      else { $continued = 0; $list = $rest; }     # Loop for handling continuation records      for (;;)    {    while (substr($list, -1) eq "\n") { chop($list); }    while (substr($list, -1) eq " ")  { chop($list); }    # Loop for scanning the list of services         while ($list ne "")      {      if (index($list, " ") >= 0)        {          ($servicename,$list) = split(/\s+/, $list, 2);         }      else        {        $servicename = $list;        $list = "";          # Check for closing bracket at end of line. It may or may not        # be preceded by a space.                        if ($continued && substr($servicename, -1) eq ")")          {          chop($servicename);          $continued = 0;          }             }              # Check the service if required. $servicename can be empty if      # a closing bracket is preceded by a space.              if ("$services" ne "" && $servicename ne "")        {         if (system("$grep \'^$servicename[ \t]\' $services >/dev/null")/256)          {          do error("\"$servicename\" does not appear in $services");          }        }       }          print FORWARD "$pref  $rest";    return if !$continued;            # Read in the next line, which contains more services, for the    # next time round this loop.         $_ = <SOURCE>;    $nline++;     ($list) = $_ =~ /^\s*(.+)$/;      $rest = "$list\n";     $pref = "  ";     }  }     # Else we have a bad recorddo error("unknown record type.");}###################################################           Generate the zone data               ###################################################sub generate_zones{local($i);$lastname = "";$nline = 0;print "Generating the zone data...\n" if $chatty;# Open the input fileopen(SOURCE, "$source_file") ||  do give_up("unable to open $source_file");# Open the output filesopen(FORWARD, ">$forward_file.new") ||  do give_up("unable to open $forward_file.new");  for ($i = 0; $i < $rzone_count; $i++)  {  open("REVERSE$i", ">$rzone_file[$i].new") ||    do give_up("unable to open $rzone_file[$i].new");  }    # Copy the SOA record into all the output filesfor ($nline = 1; $nline <= $soa_count; $nline++)  {  $_ = <SOURCE>;  print FORWARD $_;  do print_reverse($_);    }  # Copy all the NS records for these zones to all the outputs. Stop# on reaching a non-NS record or a record with a name field. Skip# blank lines, and handle comments as normal.$nline--;for (;;)  {  $_ = <SOURCE>;  $nline++;   if (/^;/) { do handle_comment(); next; }   next if /^\s*$/;   last if /^\S/;  local($ttl,$class,$ns) = /^\s+(\d+\s+|)(IN\s+|)NS\s+(\S+)\s*$/;   last if $ns eq "";  do check_fqn($ns, "NS");  print FORWARD $_;  do print_reverse($_);   }   # OK, now we have the first general record in $_. We can now scan# the rest of the file, processing as required. We do a check on# the first character of the line, because it is easy in moments# of absent-mindedness to do silly things like put in comments with# a sharp sign character instead of a semicolon. Let through only# those characters that can legally begin a line.  for (;;)  {  if (!/^\s*$/)    {    if (!/^[\s\da-zA-Z\;>\"@\*]/)      { do error("invalid line - semicolon omitted?"); }    elsif (substr($_, 0, 1) eq ";")       { do handle_comment(); }    else       { do handle_record(); }      }    last if ! ($_ = <SOURCE>);    $nline++;   }# Close all the filesclose FORWARD;close SOURCE;  for ($i = 0; $i < $rzone_count; $i++) { close("REVERSE$i"); }}###################################################        Rescan source for CNAME check           ###################################################sub cname_check{$nline = 0;$lastname = "";print "Re-reading the source file for CNAME check...\n" if $chatty;# Open the input fileopen(SOURCE, "$source_file") ||  do give_up("unable to open $source_file");# Skip the SOA recordfor ($nline = 1; $nline <= $soa_count; $nline++) { $_ = <SOURCE>; }  $nline--;# Scan for CNAMEs. We only need to do a very little parsing,# as all checking has previously been done. We must still# do the lastname stuff, to catch cases of a CNAME record# followed by nameless records.for (;;)  {  last if ! ($_ = <SOURCE>);    $nline++;   if (!/^\s*$/ && substr($_, 0, 1) ne ";")    {    if (/^>(E|F|R) /) { $rest = substr($_, 3); }      else { $rest = $_; }           ($name,$rest) = split(/\s+/, $rest, 2);    $name = $lastname if $name eq "";    $lastname = $name;    if ($rest =~ /^\d/) { ($ttl,$rest) = split(/\s+/, $rest, 2); }    ($class,$rest) = split(/\s+/, $rest, 2);    if ($class eq "IN")      { ($type,$rest) = split(/\s+/, $rest, 2); }    else { $type = $class; }    if ($type ne "CNAME" && $cnames{$name} ne "")      {      do error("$name appears on a CNAME record (line $cnames{$name}) and ".        "so may not\n   appear on any other records.");      }     }    }close SOURCE;  }###################################################           Compare new/old zone lengths         ###################################################sub check_length{local($length_old, $length_new, $length_diff);local($name) = $_[0];if (! -e $name)  {  do give_up("$name is unavailable for length checking.");  return;  }   @stat_data = stat($name);$length_old = $stat_data[7];@stat_data = stat("$name.new");$length_new = $stat_data[7];$length_diff = $length_old - $length_new;if ($length_diff > ($length_old/20))  {  do error("$name.new is more than 5% shorter than $name.\n".    "** Use -short to override this check.");    $lastwaserror = 1;   } elsif ($chatty)  {  print "\n" if $lastwaserror;   print "Length of $name is OK\n";  $lastwaserror = 0;   }   }sub compare_lengths{local($i);print "Comparing lengths of old and new zone files...\n" if $chatty;$lastwaserror = 0;do check_length("$forward_file");for ($i = 0; $i < $rzone_count; $i++)  {  do check_length("$rzone_file[$i]");  }  }###################################################         Rename new zones to final names        ###################################################sub rename_zones {local($i);print "Renaming the new zone files to their final names...\n" if $chatty;rename("$forward_file.new", "$forward_file");for ($i = 0; $i < $rzone_count; $i++)  { rename("$rzone_file[$i].new", "$rzone_file[$i]"); }}###################################################           Remove temporary files               #################################################### This is used to remove the temporary files if processing# fails. It is not an error for the temps not to exist.sub remove_temps{local ($i);unlink "$forward_file.new";for ($i = 0; $i < $rzone_count; $i++)  { unlink "$rzone_file[$i].new"; }}###################################################                Main Program                    #################################################### After any serious error, the script dies and does not# return to the main code. Syntax errors etc. carry on,# leaving $errors containing the count. Only generate_zones()# cname_check() and compare_lengths() handle errors in this #way - all the other routines generate hard errors.$rzone_count = $errors = 0;$soa_count = 6;do unpick_args();do verify();do update_serial();do generate_zones();print "\n" if $errors > 0;do cname_check();$nline = -1;if ($errors == 0)  {  do compare_lengths() if !$opt_short;  if ($errors == 0)    {      do rename_zones();    print "\nMakezones completed successfully.\n";    exit 0;    }   }do remove_temps(); print "\n** Makezones failed.\n";exit 99;# End of makezones 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -