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

📄 dns2hosts

📁 早期freebsd实现
💻
字号:
#!/usr/bin/perl## $Id: dns2hosts,v 2.0 90/09/11 11:07:27 hakanson Rel $## Convert DNS master (RFC-1035) files to /etc/hosts format.#   Marion Hakanson (hakanson@cse.ogi.edu)#   Oregon Graduate Institute of Science and Technology## Copyright (c) 1990, Marion Hakanson.## You may distribute under the terms of the GNU General Public License# as specified in the README file that comes with the dnsparse kit.## Other than "-d defdom" (to specify a default domain different from that# found in /etc/resolv.conf), command line args are DNS master file names,# as described for the dns_init() subroutine in dnsparse.pl.  The output# is printed to the standard output stream.## This Perl program looks at the A and CNAME records encountered in the# DNS master files, and produces an /etc/hosts file which includes the# same host-to-address, address-to-host, and alias-to-host mappings.# Note that some such mappings are necessarily dependent on the order in# which they are encountered in the DNS master files.  The DNS system# is not sensitive to the order, but /etc/hosts files are, thus one# should take care that the command line arguments are presented in# the same order from one invocation to the next, if one expects the# two resulting output files to be comparable.## A large part of the complication of this program is due to the notion# of the "default domain" that the BIND implementation of a DNS resolver# provides.  Namely, this allows a user to type a short alias and have# it match to a fully qualified domain name (FQDN) somewhere in the# machine's default domain.  E.g. given "admin" and a default domain# of "cse.ogi.edu", the resolver will try "admin.cse.ogi.edu" -- if no# match is found, it will try "admin.ogi.edu" (but it will not try# just the first-level domain, "admin.edu").## Thus, the aliases and canonical names are set up in the output file# to mimic the behavior of a system using the BIND resolver.  Among# other things, this means that host numbers will always be resolved# to the FQDN of the host.  Instead of using PTR records to provide# the number-to-name mappings, this program assumes that the PTR records# would be automatically generated from the A records.  It further assumes# that a host is considered to have a single, unique FQDN, and that all# of its addresses (interfaces) will resolve back to that FQDN.  To my# knowledge, this is the only area where the output hosts file may not# quite mimic the behavior of the BIND resolver.  I would be willing to# consider a design change if demand warrants it.do 'getopts.pl'; die "$@, aborted" if $@;do 'dnsparse.pl'; die "$@, aborted" if $@;do Getopts('d:');# Get default domainif ( defined($opt_d) ) {  $defdom = $opt_d;} elsif ( open(F, '</etc/resolv.conf') ) {  while ( <F> ) {    $defdom = $1 if ( /\s*domain\s+([^\s]+)/ );  }  close(F);}# Set up domains the resolver would tryif ( defined($defdom) ) {  $defdom =~ s/^\.//;	# strip leading dot  $defdom = do dns_makefqdn($defdom,'');  @domparts = split(/\./,$defdom);	# escaped dots?  while ( $#domparts > 0 ) {    push(@defdoms, join('.',@domparts));    shift(@domparts);  }}# Parse the dns db file, collecting names & addrs.do dns_init(@ARGV);open(OFILE, ">&STDOUT") || die "Cannot dupe 'STDOUT', aborted";# Treat loopback address specially, since the DNS is usually set# up to resolve loopback to "localhost".$hostsbyaddr{'127.0.0.1'} = 'localhost';push(@addrs,'127.0.0.1');rr: while ( (@rr = do dns_getrr()) && @rr ) {  ($domain, $ttl, $class, $type, @data) = @rr;  next rr if ( $class ne 'IN' );  case: {    if ( $type eq 'A' ) {      $list = '';      if ( defined($hostsbyaddr{$data[0]}) ) {        $list = $hostsbyaddr{$data[0]} . $dns'delim;      } else {        push(@addrs,$data[0]);      }      $list .= $domain;      $hostsbyaddr{$data[0]} = $list;      $fqdnseen{$domain}++;      last case;    } elsif ( $type eq 'CNAME' ) {      $list = '';      if ( defined($cnamesbyhost{$data[0]}) ) {        $list = $cnamesbyhost{$data[0]} . $dns'delim;      }      $list .= $domain;      $cnamesbyhost{$data[0]} = $list;      $fqdnseen{$domain}++;      last case;    }  }}# Go through the names encountered, building abbreviations,# and attaching them to their fully-qualified forms.while ( ($fqdn,$cnt) = each %fqdnseen ) {  #print STDERR "$fqdn seen $cnt times\n";  foreach $truncdom (@defdoms) {    $abbrev = $fqdn;    # don't generate abbrev's which wouldn't resolve    if ( $abbrev =~ s/\.$truncdom// ) {      # now we mimic what the resolver would do      foreach $dom (@defdoms) {        if ( defined($fqdnseen{"$abbrev.$dom"}) ) {          $abbrevsbyhost{"$abbrev.$dom"} .= $abbrev . $dns'delim;          #print STDERR "$abbrev -> $abbrev.$dom\n";          # stop with the first one          last;        }      }    }  }}# for debugging#while ( ($key,$val) = each(%abbrevsbyhost) ) {#  print STDERR "|$key";#  @vals = split(/$dns'delim/,$val);#  foreach $val (@vals) {#    print STDERR "|$val";#  }#  print STDERR "|\n";#}# Write out the hosts file.# First write out some commentary about the input source, etc.$datefmt = '%02d/%02d/%02d %02d:%02d:%02d';($sec,$min,$hour,$mday,$mon,$year,@rest) = localtime();$mon++;	# 0 == January$date = sprintf($datefmt, $year, $mon, $mday, $hour, $min, $sec);chop($host = `hostname`);print OFILE "#\n";print OFILE "# Host table (/etc/hosts)\n";print OFILE "#\n";print OFILE "# Created on host '$host' at $date\n";print OFILE "#\n";print OFILE "# Abbreviations set up for default domain '$defdom'\n";print OFILE "#\n";print OFILE "#   THIS TABLE WAS GENERATED AUTOMATICALLY.\n";print OFILE "#   ANY CHANGES OR ADDITIONS TO IT WILL BE\n";print OFILE "#   LOST WHEN THE NEXT UPDATE TAKES PLACE.\n";print OFILE "#\n";print OFILE "# Built from the following DNS master files:\n";print OFILE "#\n";print OFILE "# ModTime\t\tFile\n";print OFILE "#\tOrigin\n";while ( $#ARGV >= $[ ) {    ($file,$origin) = do dns_commasplit(shift(@ARGV));    $origin = '.' unless ( $origin );	# root    if ( $file eq '' || $file eq '-' ) {        $file eq 'Standard Input';        @ARGV = ();	# STDIN is last        $date = 'See Above';    } else {        if ( -r $file ) {            ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,                $atime,$mtime,$ctime,$blksize,$blocks) = stat(_);            ($sec,$min,$hour,$mday,$mon,$year,@rest) = localtime($mtime);            $mon++;	# 0 == January            $date = sprintf($datefmt, $year, $mon, $mday, $hour, $min, $sec);        } else {            $date = "Not Found";            $origin = $!;	# the error message        }    }    print OFILE "# $date\t$file\n";    print OFILE "#\t$origin\n";}print OFILE "#\n";print OFILE "#\n";# Build up an output record and then write it out using a# format which may break a long record into multiple lines,# all starting with the same address and canonical name.format OFILE =@<<<<<<<<<<<<<<  ~^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<$addr,              $names.$: = ' ';	# OK to break $names on a blankforeach $addr ( @addrs ) {  @hosts = split(/$dns'delim/, $hostsbyaddr{$addr});  %nameseen = ();  $names = '';  $canon = $hosts[0];		# save the first one  foreach $host ( @hosts ) {    unless ( defined($nameseen{$host}) ) {      $nameseen{$host} = 1;      $names .= " $host";      if ( defined($abbrevsbyhost{$host}) ) {        @abbrevs = split(/$dns'delim/, $abbrevsbyhost{$host});        foreach $abbrev ( @abbrevs ) {          unless ( defined($nameseen{$abbrev}) ) {            $nameseen{$abbrev} = 1;            $names .= " $abbrev";          }        }      }    }    if ( defined($cnamesbyhost{$host}) ) {      @aliases = split(/$dns'delim/, $cnamesbyhost{$host});      foreach $alias ( @aliases ) {        unless ( defined($nameseen{$alias}) ) {          $nameseen{$alias} = 1;          $names .= " $alias";          if ( defined($abbrevsbyhost{$alias}) ) {            @abbrevs = split(/$dns'delim/, $abbrevsbyhost{$alias});            foreach $abbrev ( @abbrevs ) {              unless ( defined($nameseen{$abbrev}) ) {                $nameseen{$abbrev} = 1;                $names .= " $abbrev";              }            }          }        }      }    }  }  $names =~ s/^ $canon *//;	# we'll put it back below  do {    #print STDERR "|$names|\n";    $names = "$canon $names";    write(OFILE);	# has side effect of shortening $names  } while ( $names );}exit(0);

⌨️ 快捷键说明

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