home *** CD-ROM | disk | FTP | other *** search
/ CD Actual Thematic 7: Programming / CDAT7.iso / Share / Editores / Perl5 / perl / lib / site / Net / Domain.pm < prev    next >
Encoding:
Perl POD Document  |  1997-08-10  |  6.3 KB  |  300 lines

  1. # Net::Domain.pm
  2. #
  3. # Copyright (c) 1995-1997 Graham Barr <gbarr@ti.com>. All rights reserved.
  4. # This program is free software; you can redistribute it and/or
  5. # modify it under the same terms as Perl itself.
  6.  
  7. package Net::Domain;
  8.  
  9. require Exporter;
  10.  
  11. use Carp;
  12. use strict;
  13. use vars qw($VERSION @ISA @EXPORT_OK);
  14. use Net::Config;
  15.  
  16. @ISA = qw(Exporter);
  17. @EXPORT_OK = qw(hostname hostdomain hostfqdn domainname);
  18.  
  19. $VERSION = do { my @r=(q$Revision: 2.5.2 $=~/\d+/g); sprintf "%d."."%02d"x$#r,@r};
  20.  
  21. my($host,$domain,$fqdn) = (undef,undef,undef);
  22.  
  23. # Try every conceivable way to get hostname.
  24.  
  25. sub _hostname {
  26.  
  27.     # we already know it
  28.     return $host
  29.         if(defined $host);
  30.  
  31.     ($^O eq 'MSWin32'
  32.      && do {
  33.     require Sys::Hostname;
  34.     $host = Sys::Hostname::hostname();
  35.     })
  36.  
  37.     # syscall is preferred since it avoids tainting problems
  38.     || eval {
  39.         my $tmp = "\0" x 256; ## preload scalar
  40.         eval {
  41.             package main;
  42.              require "syscall.ph";
  43.         }
  44.         || eval {
  45.             package main;
  46.              require "sys/syscall.ph";
  47.         }
  48.         and $host = (syscall(&main::SYS_gethostname, $tmp, 256) == 0)
  49.         ? $tmp
  50.         : undef;
  51.     }
  52.  
  53.     # POSIX
  54.     || eval {
  55.     require POSIX;
  56.     $host = (POSIX::uname())[1];
  57.     }
  58.  
  59.     # trusty old hostname command
  60.     || eval {
  61.         chop($host = `(hostname) 2>/dev/null`); # BSD'ish
  62.     }
  63.  
  64.     # sysV/POSIX uname command (may truncate)
  65.     || eval {
  66.         chop($host = `uname -n 2>/dev/null`); ## SYSV'ish && POSIX'ish
  67.     }
  68.  
  69.     # Apollo pre-SR10
  70.     || eval {
  71.         $host = (split(/[:\. ]/,`/com/host`,6))[0];
  72.     }
  73.  
  74.     || eval {
  75.         $host = "";
  76.     };
  77.  
  78.     # remove garbage 
  79.     $host =~ s/[\0\r\n]+//go;
  80.     $host =~ s/(\A\.+|\.+\Z)//go;
  81.     $host =~ s/\.\.+/\./go;
  82.  
  83.     $host;
  84. }
  85.  
  86. sub _hostdomain {
  87.  
  88.     # we already know it
  89.     return $domain
  90.         if(defined $domain);
  91.  
  92.     return $domain = $NetConfig{'inet_domain'}
  93.     if defined $NetConfig{'inet_domain'};
  94.  
  95.     # try looking in /etc/resolv.conf
  96.     # putting this here and assuming that it is correct, eliminates
  97.     # calls to gethostbyname, and therefore DNS lookups. This helps
  98.     # those on dialup systems.
  99.  
  100.     local *RES;
  101.  
  102.     if(open(RES,"/etc/resolv.conf")) {
  103.         while(<RES>) {
  104.             $domain = $1
  105.                 if(/\A\s*(?:domain|search)\s+(\S+)/);
  106.         }
  107.         close(RES);
  108.  
  109.         return $domain
  110.             if(defined $domain);
  111.     }
  112.  
  113.     # just try hostname and system calls
  114.  
  115.     my $host = _hostname();
  116.     my(@hosts);
  117.     local($_);
  118.  
  119.     @hosts = ($host,"localhost");
  120.  
  121.     unless($host =~ /\./) {
  122.     my $dom = undef;
  123.         eval {
  124.             my $tmp = "\0" x 256; ## preload scalar
  125.             eval {
  126.                 package main;
  127.                  require "syscall.ph";
  128.             }
  129.             || eval {
  130.                 package main;
  131.                  require "sys/syscall.ph";
  132.             }
  133.             and $dom = (syscall(&main::SYS_getdomainname, $tmp, 256) == 0)
  134.             ? $tmp
  135.             : undef;
  136.         };
  137.  
  138.     chop($dom = `domainname 2>/dev/null`)
  139.         unless(defined $dom);
  140.  
  141.     if(defined $dom) {
  142.         my @h = ();
  143.         while(length($dom)) {
  144.         push(@h, "$host.$dom");
  145.         $dom =~ s/^[^.]+.//;
  146.         }
  147.         unshift(@hosts,@h);
  148.         }
  149.     }
  150.  
  151.     # Attempt to locate FQDN
  152.  
  153.     foreach (@hosts) {
  154.         my @info = gethostbyname($_);
  155.  
  156.         next unless @info;
  157.  
  158.         # look at real name & aliases
  159.         my $site;
  160.         foreach $site ($info[0], split(/ /,$info[1])) { 
  161.             if(rindex($site,".") > 0) {
  162.  
  163.                 # Extract domain from FQDN
  164.  
  165.                  ($domain = $site) =~ s/\A[^\.]+\.//; 
  166.                  return $domain;
  167.             }
  168.         }
  169.     }
  170.  
  171.     # Look for environment variable
  172.  
  173.     $domain ||= $ENV{LOCALDOMAIN} ||= $ENV{DOMAIN} || undef;
  174.  
  175.     if(defined $domain) {
  176.         $domain =~ s/[\r\n\0]+//g;
  177.         $domain =~ s/(\A\.+|\.+\Z)//g;
  178.         $domain =~ s/\.\.+/\./g;
  179.     }
  180.  
  181.     $domain;
  182. }
  183.  
  184. sub domainname {
  185.  
  186.     return $fqdn
  187.         if(defined $fqdn);
  188.  
  189.     _hostname();
  190.     _hostdomain();
  191.  
  192.     # Assumption: If the host name does not contain a period
  193.     # and the domain name does, then assume that they are correct
  194.     # this helps to eliminate calls to gethostbyname, and therefore
  195.     # eleminate DNS lookups
  196.  
  197.     return $fqdn = $host . "." . $domain
  198.     if($host !~ /\./ && $domain =~ /\./);
  199.  
  200.     my @host   = split(/\./, $host);
  201.     my @domain = split(/\./, $domain);
  202.     my @fqdn   = ();
  203.  
  204.     # Determine from @host & @domain the FQDN
  205.  
  206.     my @d = @domain;
  207.  
  208. LOOP:
  209.     while(1) {
  210.         my @h = @host;
  211.         while(@h) {
  212.             my $tmp = join(".",@h,@d);
  213.             if((gethostbyname($tmp))[0]) {
  214.                  @fqdn = (@h,@d);
  215.                  $fqdn = $tmp;
  216.                last LOOP;
  217.             }
  218.             pop @h;
  219.         }
  220.         last unless shift @d;
  221.     }
  222.  
  223.     if(@fqdn) {
  224.         $host = shift @fqdn;
  225.         until((gethostbyname($host))[0]) {
  226.             $host .= "." . shift @fqdn;
  227.         }
  228.         $domain = join(".", @fqdn);
  229.     }
  230.     else {
  231.         undef $host;
  232.         undef $domain;
  233.         undef $fqdn;
  234.     }
  235.  
  236.     $fqdn;
  237. }
  238.  
  239. sub hostfqdn { domainname() }
  240.  
  241. sub hostname {
  242.     domainname()
  243.         unless(defined $host);
  244.     return $host;
  245. }
  246.  
  247. sub hostdomain {
  248.     domainname()
  249.         unless(defined $domain);
  250.     return $domain;
  251. }
  252.  
  253. 1; # Keep require happy
  254.  
  255. __END__
  256.  
  257. =head1 NAME
  258.  
  259. Net::Domain - Attempt to evaluate the current host's internet name and domain
  260.  
  261. =head1 SYNOPSIS
  262.  
  263.     use Net::Domain qw(hostname hostfqdn hostdomain);
  264.  
  265. =head1 DESCRIPTION
  266.  
  267. Using various methods B<attempt> to find the Fully Qualified Domain Name (FQDN)
  268. of the current host. From this determine the host-name and the host-domain.
  269.  
  270. Each of the functions will return I<undef> if the FQDN cannot be determined.
  271.  
  272. =over 4
  273.  
  274. =item hostfqdn ()
  275.  
  276. Identify and return the FQDN of the current host.
  277.  
  278. =item hostname ()
  279.  
  280. Returns the smallest part of the FQDN which can be used to identify the host.
  281.  
  282. =item hostdomain ()
  283.  
  284. Returns the remainder of the FQDN after the I<hostname> has been removed.
  285.  
  286. =back
  287.  
  288. =head1 AUTHOR
  289.  
  290. Graham Barr <gbarr@ti.com>.
  291. Adapted from Sys::Hostname by David Sundstrom <sunds@asictest.sc.ti.com>
  292.  
  293. =head1 COPYRIGHT
  294.  
  295. Copyright (c) 1995-1997 Graham Barr. All rights reserved.
  296. This program is free software; you can redistribute it and/or modify
  297. it under the same terms as Perl itself.
  298.  
  299. =cut
  300.